【问题标题】:AnimatedSwitcher not working as intended? Widget changing but no animationAnimatedSwitcher 没有按预期工作?小部件更改但没有动画
【发布时间】: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。上课。

标签: flutter flutter-layout flutter-animation


【解决方案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,
          ),
  );

【讨论】:

【解决方案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;
            }

【讨论】:

    猜你喜欢
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2018-11-07
    • 2018-11-01
    • 1970-01-01
    • 2021-10-19
    • 2020-03-18
    相关资源
    最近更新 更多