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

Posted

技术标签:

【中文标题】AnimatedSwitcher 没有按预期工作?小部件更改但没有动画【英文标题】:AnimatedSwitcher not working as intended? Widget changing but no animation 【发布时间】:2019-12-24 04:08:18 【问题描述】:

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

为此,我正在使用 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 之前,它曾经正常运行。

【问题讨论】:

将您的方法重构为实际的类。那应该可以解决它。 @RémiRousselet 能否请您举一个小例子说明它的外观? @RémiRousselet 你能解释一下为什么这些方法不起作用,但实际类可以吗? @EmilAdz 方法不会创建新的 BuildContext。上课。 【参考方案1】:

如果您要切换的新小部件与之前的小部件类型相同,请将 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,
          ),
  );

因为我们要在两个Containers 之间切换,而AnimatedSwitcher 无法理解它们的区别,所以没有动画它们的切换。 如果我们在这些Containers 中设置不同的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,
          ),
  );

【讨论】:

为此浪费了几个小时,谢谢!但是你怎么知道的? 他们在这里提到:youtube.com/watch?v=LKKgYpC-EPQ&ab_channel=Flutter 你救了我。非常感谢!【参考方案2】:

你可以试试这个

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"),
      ],
    );
  

【讨论】:

它是有效的,但看起来像一些解决方法,有人有其他解决方案吗?【参考方案3】:

我也遇到了这个问题,并且几天后无法解决,即使我使用 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;
            

【讨论】:

以上是关于AnimatedSwitcher 没有按预期工作?小部件更改但没有动画的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 SUM() 字段没有按预期工作?

为啥响应式表没有按预期工作?

为啥脚手架没有按预期工作?

否定字符没有按预期工作? ^

为啥我的替换没有按预期工作[重复]

为啥我的查询没有按预期工作?