AnimatedSwitcher 没有按预期工作?小部件更改但没有动画

AnimatedSwitcher not working as intended? Widget changing but no animation

目标:按下一个按钮,让它切换到另一个带有动画过渡的页面。

为此,我正在使用 AnimatedSwitcher。

下面是我的代码:

class WelcomeScreenSwitcher extends State<RandomWords>{
  Widget calledWidget;

  void switchPage(int newNumber, context) {
    if (newNumber == 1) {
      setState(() {calledWidget = welcomeScreen(context);},);
    } else if (newNumber == 2) {
      setState(() {calledWidget = learnMoreScreen(context);},);}
    }

  @override
  Widget build(BuildContext context) {
    if (calledWidget == null) {
      switchPage(1, context);
    }
    return AnimatedSwitcher(
      duration: Duration(milliseconds: 5000),
      child: calledWidget,
    );

  Widget welcomeScreen(context){
    return Scaffold({body: Column(children: [
      RaisedButton(onPressed: () {switchPage(2, context);}, child: Text('B'),),],
        );
      });
    }

  Widget learnMoreScreen(context){
    return Scaffold({body: Column(children: [
      RaisedButton(onPressed: () {switchPage(2, context);}, child: Text('B'),),],
        );
      });
    }
  }

代码有效。它确实会在两个页面之间切换,但没有相应的动画。

在开发过程中的某个时刻,我得到了动画,但后来它就停止了,我找不到原因。我不记得有任何关于我如何调用 AnimatedSwitcher 的具体更改。

如果它有任何用处,热重载也不再起作用了。我需要重新启动应用程序才能进行任何更改注册。在开始使用 AnimatedSwitcher 之前,它曾经正常运行。

你可以试试这个

class _AniSwitchState extends State<AniSwitch> {
  Widget calledWidget;

  @override
  Widget build(BuildContext context) {
    void switchPage(int newNumber) {
      if (newNumber == 1) {
        setState(() {calledWidget = WelcomeScreen();},);
      } else if (newNumber == 2) {
        setState(() {calledWidget = LearnMoreScreen();},);}
    }

      if (calledWidget == null) {
        switchPage(1);
      }

    return Column(
      children: <Widget>[
        AnimatedSwitcher(
          duration: Duration(milliseconds: 2000),
          child: calledWidget
        ),
        RaisedButton(
          child: const Text('Increment'),
          onPressed: () {
            setState(() {
              switchPage(2);
            });
          },
        ),
      ],
    );
  }
}

class WelcomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text("Welcome"),
      ],
    );
  }
}

class LearnMoreScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text("hello world"),
      ],
    );
  }
}

如果您要切换的新小部件与之前的小部件类型相同,请将 key 属性 设置为另一个值以获得该动画

例如,这个 AnimatedSwitcher 不起作用:

  AnimatedSwitcher(
    duration: const Duration(milliseconds: 1000),
    child: (condition)
        ? Container(
            width: 100,
            height: 100,
            color: Colors.red,
          )
        : Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
  );

因为我们要在两个Container之间切换,而AnimatedSwitcher无法理解它们的区别,所以它没有动画它们的切换。 如果我们在那些 Container 中设置不同的 key 属性,那么 AnimatedSwitcher 可以理解它们的不同并为它们的开关设置动画。

就像这样:

  AnimatedSwitcher(
    duration: const Duration(milliseconds: 1000),
    child: (condition)
        ? Container(
            key: ValueKey<int>(0),
            width: 100,
            height: 100,
            color: Colors.red,
          )
        : Container(
            key: ValueKey<int>(1),
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
  );

我也有这个问题,几天后无法解决,我给了我的小部件不同的键,即使我使用 AnimatedSwitcher 的 layoutBuilder 将前面的小部件包裹在 Conrainer() 周围每次更改时都会给出 UniqueKey(),所以它可能会起作用,但仍然没有用。

我的代码;

           RxInt currentTab = 0.obs;

           RxList<Map<String, Widget>> stepList = [
             {
               'title': Text('Adres Bilgisi'),
               'view': Step1(key: ValueKey(1),)
             },
             {
               'title': Text('Adres Bilgisi'),
               'view': Step2(key: ValueKey(2),),
             },
             {
               'title': Text('Gönderi Detayı'),
               'view': Step3(key: ValueKey(3),),
             }
           ].obs;

           SliverToBoxAdapter(
              child: Obx(() => AnimatedSwitcher(
                key: Key('switcher.tab'),
                duration: new Duration(microseconds: 500),
                switchInCurve: Curves.easeIn,
                layoutBuilder: (currentChild, previousChildren) {
                  return Container(
                    key: UniqueKey(),
                    child: AnimatedSwitcher.defaultLayoutBuilder(currentChild, previousChildren),
                  );
                },
                transitionBuilder: (Widget child, Animation<double> animation) {
                  /*final offsetAnimation = Tween(
                  begin: const Offset(1.0, 0.0),
                  end: const Offset(0.0, 0.0),
                ).animate(animation);
                // 3.
                return ClipRect(
                  child: SlideTransition(
                    position: offsetAnimation,
                    child: child,
                  ),
                );*/
                  return ScaleTransition(scale: animation, child: child);
                },
                child: controller.tabs[controller.currentTab.value.toInt()],
              )),
            )

这是我更改当前选定小部件的 TabBar 代码;

            TabBarWidget(
              height: 60,
              initialSelectedId: 0,
              tag: 'advertform.tab',
              tabs: [
                ChipWidget(
                  tag: 'advertform.tab',
                  text: "1".tr,
                  id: 0,
                  onSelected: (id) {
                    controller.prevStep.value = controller.onStep.value;
                    controller.onStep.value = id;
                    controller.changeTab(id);
                  },
                ),
                ChipWidget(
                  tag: 'advertform.tab',
                  text: "2".tr,
                  id: 1,
                  onSelected: (id) {
                    controller.prevStep.value = controller.onStep.value;
                    controller.onStep.value = id;
                    controller.changeTab(id);
                  },
                ),
                ChipWidget(
                  tag: 'advertform.tab',
                  text: "3".tr,
                  id: 2,
                  onSelected: (id) {
                    controller.prevStep.value = controller.onStep.value;
                    controller.onStep.value = id;
                    controller.changeTab(id);
                  },
                ),
              ],
            )

            void changeTab(int index) {
              currentTab.value = index;
            }