微信交流群

# Google 工程师带你选择 Flutter 动画控件

对初学者来说,看完这篇文章,我想你脑瓜子一定是嗡嗡的,这都说的是什么啊。

不要急躁,开始的我和你是一样的,第一遍看完,完全不知道在说什么,不明白不要紧,请先收藏此文章,然后先去学习下 Flutter 内置的 25 种动画组件。

不要仅仅是看,要多写,只有写才能发现问题。

当你对动画控件有了一定的了解,在回过头来细细的品一品这篇文章,你会有不一样的感受,你品,你细品。

这篇文章的内容是 Google 的 Flutter 工程师 Emily 原创,我仅仅是翻译,原创地址:https://www.youtube.com/watch?v=GXIJJkq_H8g

从广义上来说,Flutter 动画组件分为两种类型,

  • Drawing-based animations:基于绘制的动画,就像是画画一样,通常都是独立的控件,例如游戏角色或者很难用纯碎的代码来完成的效果。
  • Core-based animations:基于核心的动画,它面向组件,基于标准的布局和样式,从本质上说,倾向于增强控件的外观和过渡效果,而不是自己充当独立的控件。

想一想你的动画是基于绘制的,还是基于核心(组件)的:

  • 如果是基于绘制的,而且你的团队中有专门的设计人员提供素材,建议你使用第三方工具,比如 Rive 和 Lottie,这些库可以方便的导入资源来构建动画。
  • 如果是基于核心(组件)的,涉及组件的变化,比如颜色、形状、位置的变化等。

在 Flutter 中基于核心(组件)的动画又分为两类:

  • 隐式动画控件:只需提供给组件开始、结束值,系统执行动画,比如 AnimatedAlign 等组件。
  • 显式动画控件:需要设置 AnimationController,控制动画的执行,使用显式动画可以完成任何隐式动画的效果,甚至功能更丰富一些,不过你需要管理该动画的 AnimationController 生命周期,AnimationController 并不是一个控件,所以需要将其放在 stateful 控件中。

从上面的分类中,我们不难看出,使用隐式动画控件,代码更简单,而且无需管理 AnimationController 的生命周期。

如何确定使用隐式动画控件还是显式动画控件?你需要考虑 3 个问题:

  • 动画是否一直重复,比如音乐播放。
  • 动画值是否不连续,比如一个圆圈,不连续的尺寸变化:小->大,小->大,小->大。连续的尺寸变化:小->大->小->大。
  • 是否有多个组件一起动画。

如果你对这三个问题中的任何一个回答“是”,那么你需要使用显式动画控件,否则你就使用隐式动画控件。

一旦你确定了使用显式动画控件或者隐式动画控件,这个时候你就需要找到对应的组件,你需要的组件是否已经在 Flutter 中内置了?

对于隐式组件来说:

  • 已经内置:直接使用,当然也可以看下 AnimatedContainer 组件,AnimatedContainer 是非常强大且用途广泛的动画组件。
  • 未内置:可以使用 TweenAnimationBuilder 创建一个自定义的动画控件。

对于显示组件来说:

  • 内置:直接使用相关组件,比如 xxxTransition 组件。
  • 未内置:自定义一个动画控件。

自定义一个显式的动画组件需要确认这个动画组件是单独一个组件还是组件的一部分,

  • 单独一个显示组件:你应该继承 AnimatedWidget 来实现。
  • 组件的一部分:使用 AnimatedBuilder 来实现。

还有最后一件事情需要考虑:如果你发现由 CustomPainter 引起的性能问题,你可以像 AnimatedWidget 一样使用它,但是 CustomPainer 直接绘制到画布上,而无需标准的小部件构建范例,如果使用的好,可以创建一些整洁、丰富的自定义的效果或者节省性能,但如果使用的不好,你的动画可能引起更多的性能问题,就像是手动管理内存一样,要处理好共享指针,为什么要用这样用,是否有内存问题,这些问题都要考虑清楚。

最后总结如下图: