为了账号安全,请及时绑定邮箱和手机立即绑定

Flutter | 求求你们了,切换 Widget 的时候加上动画吧

标签:
WebApp

平时我们在切换 Widget 的时候是怎样的?

有没有动画效果?是不是直接改变了一个 Widget?

类似于这样的:
图片描述

如果是的话,那么今天所说的 Widget,绝对符合你的口味。

那如何在 Flutter 当中切换 Widget 的时候加上特效?完成这样的效果?
图片描述

AnimatedSwitcher 了解一下。

AnimatedSwitcher

官方介绍

话不多说,功能我们已经了解,再来看一下官方的介绍:

A widget that by default does a FadeTransition[1] between a new widget and the widget previously set on the AnimatedSwitcher[2] as a child.

If they are swapped fast enough (i.e. before duration[3] elapses), more than one previous child can exist and be transitioning out while the newest one is transitioning in.

If the "new" child is the same widget type and key as the "old" child, but with different parameters, then AnimatedSwitcher[4] will not do a transition between them, since as far as the framework is concerned, they are the same widget and the existing widget can be updated with the new parameters. To force the transition to occur, set a Key[5] on each child widget that you wish to be considered unique (typically a ValueKey[6] on the widget data that distinguishes this child from the others).

大致意思就是:

默认情况下是执行透明度的动画。

如果交换速度足够快,则存在多个子级,但是在新子级传入的时候将它移除。

如果新 Widget 和 旧 Widget 的类型和键相同,但是参数不同,那么也不会进行转换。如果想要进行转换,那么要添加一个 Key。

构造函数

再来看构造函数,来确定如何使用:


const AnimatedSwitcher({
  Key key,
  this.child,
  @required this.duration,
  this.reverseDuration,
  this.switchInCurve = Curves.linear,
  this.switchOutCurve = Curves.linear,
  this.transitionBuilder = AnimatedSwitcher.defaultTransitionBuilder,
  this.layoutBuilder = AnimatedSwitcher.defaultLayoutBuilder,
}) : assert(duration != null),
assert(switchInCurve != null),
assert(switchOutCurve != null),
assert(transitionBuilder != null),
assert(layoutBuilder != null),
super(key: key);

来解释一下每个参数:

1.child:不用多说2.duration:动画持续时间3.reverseDuration:从新的 Widget 到旧的 Widget 动画持续时间,如果不设置则为 duration 的值4.switchInCurve:动画效果5.switchOutCurve:同上6.transitionBuilder:设置一个新的转换动画7.layoutBuilder:包装新旧 Widget 的组件,默认是一个 Stack

其中必要参数就是一个 duration,那既然知道如何使用了,那就开撸。

简单例子

前面我们看的图,就是在对 AppBar上的 actions 进行操作,

其实这个例子在实际开发当中经常存在,肯定要删除一些东西的嘛,然后选中了以后批量删除。

那这里也不多说,直接上代码,然后解释:


class _AnimatedSwitcherPageState extends State<AnimatedSwitcherPage> {
  IconData _actionIcon = Icons.delete;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('AnimatedSwitcherPage'),
          actions: <Widget>[
            AnimatedSwitcher(
              transitionBuilder: (child, anim){
                return ScaleTransition(child: child,scale: anim);
              },
              duration: Duration(milliseconds: 300),
              child: IconButton(
                  key: ValueKey(_actionIcon),
                  icon: Icon(_actionIcon),
                  onPressed: () {
                    setState(() {
                      if (_actionIcon == Icons.delete)
                        _actionIcon = Icons.done;
                      else
                        _actionIcon = Icons.delete;
                    });
                  }),
            )
          ],
        ),
        body: Container());
  }
}

我们定义的是一个 StatefulWidget,因为在切换 Widget 的时候要调用 setState()

下面来说一下整个流程:

1.首先定义好我们初始化的 Icon的数据为 Icons.delete2.在 AppBaractions 里面加入 AnimatedSwitcher3.设置 transitionBuilder 为 缩放动画 ScaleTransition4.给 AnimatedSwitcher 的 child 为 IconButton5.因为前面官方文档说过,如果 Widget 类型一样,只是数据不一样,那么想要动画,就必须添加 Key。6.所以我们给 IconButton 添加了一个 ValueKey,值就为定义好的 IconData7.最后在点击事件中切换两个 Icon 就完成了

最后再看一下效果:
图片描述

总结

使用该控件最应该注意的点就是 Key 的问题,一定要记住:

如果新 Widget 和 旧 Widget 的类型和键相同,但是参数不同,那么也不会进行转换。如果想要进行转换,那么要添加一个 Key。

References

[1] FadeTransition: https://api.flutter.dev/flutter/widgets/FadeTransition-class.html
[2] AnimatedSwitcher: https://api.flutter.dev/flutter/widgets/AnimatedSwitcher-class.html
[3] duration: https://api.flutter.dev/flutter/widgets/AnimatedSwitcher/duration.html
[4] AnimatedSwitcher: https://api.flutter.dev/flutter/widgets/AnimatedSwitcher-class.html
[5] Key: https://api.flutter.dev/flutter/foundation/Key-class.html
[6] ValueKey: https://api.flutter.dev/flutter/foundation/ValueKey-class.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
30
获赞与收藏
45

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消