Flutter Switching FAB на страницах PageView с анимацией в Scaffold

Итак, я поискал в нескольких местах, как это должно быть реализовано, и я уверен, что упускаю что-то тривиальное, но у меня есть приложение flutter с Scaffold, тело которого является PageView. Мне нужно иметь другой FAB для некоторых страниц, и в настоящее время он настроен для атрибута floatingActionButton скаффолда, настроенного для доступа к массиву FloatingActionButtons с индексом _currentPageIndex (закрытая переменная, совместно используемая bottomNavBar и _pageController.

Это резко меняет FAB, что не является желаемым поведением.

Я пытаюсь заставить FAB анимировать (масштабировать и масштабировать), когда страница изменяется, как в спецификация материала:

Tabbed Screens When tabs are present, the FAB should briefly disappear, then >reappear when the new content moves into place. This expresses >that the FAB is not connected to any particular tab.

Я был бы признателен за любой совет о том, как реализовать его просто (я почти уверен, что упускаю что-то тривиальное). Альтернатива - вручную анимировать FAB-файлы вручную, завернув их во что-нибудь.

0
0
2 138
1

Ответы 1

Вы можете попробовать использовать виджет AnimatedCrossFade примерно так:

        class TestingNewWidgetState extends State<TestingNewWidget> {
          int currentIndex = 0;

          @override
          Widget build(BuildContext context) {
            return Scaffold(
              floatingActionButton: AnimatedCrossFade(
                crossFadeState: currentIndex == 0
                    ? CrossFadeState.showFirst
                    : CrossFadeState.showSecond,
                duration: Duration(seconds: 1),
                firstChild: FloatingActionButton(
                  onPressed: () => null,
                  child: Icon(Icons.arrow_left),
                  backgroundColor: Colors.red,
                ),
                secondChild: FloatingActionButton(
                  onPressed: () => null,
                  child: Icon(Icons.arrow_right),
                  backgroundColor: Colors.blue,
                ),
              ),
              body: PageView(
                onPageChanged: (index) {
                  setState(() {
                    currentIndex = index;
                  });
                },
                children: <Widget>[
                  Scaffold(
                    body: Center(
                      child: Text("page 1"),
                    ),
                  ),
                  Scaffold(
                    body: Center(
                      child: Text("page 2"),
                    ),
                  ),
                ],
              ),
            );
          }
        }

ОБНОВИТЬ

Помните, что вы можете создать свой собственный виджет, это пример использования настраиваемого FloatingActionButton:

        class TestingNewWidgetState extends State<TestingNewWidget> {
          int currentIndex = 0;

          @override
          Widget build(BuildContext context) {
            var customFabButton;
            if (currentIndex == 0) {
              customFabButton = CustomFabButton(
                color: Colors.red,
                onPressed: () => null,
                icon: Icons.alarm,
              );
            } else if (currentIndex == 1) {
              customFabButton = CustomFabButton(
                color: Colors.blue,
                onPressed: () => null,
                icon: Icons.satellite,
              );
            } else {
              customFabButton = CustomFabButton(
                color: Colors.green,
                onPressed: () => null,
                icon: Icons.verified_user,
              );
            }

            return Scaffold(
              floatingActionButton: customFabButton,
              body: PageView(
                onPageChanged: (index) {
                  setState(() {
                    currentIndex = index;
                  });
                },
                children: <Widget>[
                  Scaffold(
                    body: Center(
                      child: Text("page 1"),
                    ),
                  ),
                  Scaffold(
                    body: Center(
                      child: Text("page 2"),
                    ),
                  ),
                  Scaffold(
                    body: Center(
                      child: Text("page 3"),
                    ),
                  ),
                ],
              ),
            );
          }
        }

        class CustomFabButton extends StatelessWidget {
          final IconData icon;
          final Color color;
          final VoidCallback onPressed;

          const CustomFabButton({Key key, this.icon, this.color, this.onPressed})
              : super(key: key);

          @override
          Widget build(BuildContext context) {
            return GestureDetector(
              onTap: onPressed,
              child: AnimatedContainer(
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: color,
                ),
                duration: Duration(seconds: 1),
                height: 50.0,
                width: 50.0,
                child: Icon(icon),
              ),
            );
          }
        }

Это будет между двумя FAB, но у меня есть 5 страниц, на 3 из которых есть FAB. Я мог бы переключить первого и второго потомков в зависимости от состояния, чтобы решить эту проблему, но я чувствую, что должно быть более простое решение, работающее по умолчанию. Может быть, мне нужно установить какое-то свойство на внешнем каркасе?

Dheeraj Y 18.12.2018 21:24

Другие вопросы по теме