[Flutter翻译]如何选择适合您的Flutter动画Widget?

908 阅读6分钟

原文地址:medium.com/flutter/how…

原文作者:medium.com/@fitzface

要观看这篇文章的视频形式,请点击这里查看我们的YouTube视频

这篇文章由Emily Fortuna原创,并以她的名义发布。

所以,你决定在你的Flutter应用程序中加入一个动画--多么令人兴奋啊!有很多不同的动画widget,所以要想知道哪一个最适合你,你会觉得不知所措。问题是,有很多不同的动画widget,所以要想知道哪一个是最合适的,可能会让人感到不知所措。幸运的是,这篇文章可以帮助你!

我将通过一系列的问题来阐述你可以问自己关于你心目中的动画的一系列问题,以帮助你确定你应该如何创建它。还有一点要记住的是,Flutter核心库中提供的动画widget是相当低级的。这意味着,如果你有一个复杂的动画,我建议你去看看pub.dev上的一些提供更高级别的动画依赖库。

看一看下面的决策树,我将在这篇文章中解释一下:

动画方案的简单决策图

大体上来说,有两种主要类型的动画,你可能希望在你的Flutter应用中包含两种类型的动画:基于绘图的动画和基于代码的动画。

相比之下,基于绘图的动画看起来就像有人画的一样。它们通常是独立的精灵,就像游戏角色一样,或者涉及到纯粹用代码来表达的转换,这很有挑战性。

所以,首先要问自己的问题是:"我的动画是更像一张图纸,还是看起来像可以用Flutter widget单元构建出来的东西?" 如果你的动画更像是一张图纸,或者你与设计团队合作,他们会提供矢量或光栅图像资源,那么我建议你使用第三方工具,比如Rive或Lottie,将你的动画以图形化的方式构建,然后导出到Flutter中。有几个软件依赖库可以帮助你在Flutter应用中加入这些资产。

否则,如果你的动画涉及到Tween widget----比如改变颜色、形状或位置----你就得写一些Flutter代码了!

显式的还是隐式的?

基于代码的Flutter动画有两种类型:隐式和显式动画。下一步是确定你需要哪种类型的动画。

当值发生变化时,隐式的动画widget会动画化。

隐式动画依赖于简单地为某些widget属性设置一个新的值,而Flutter则负责将其从当前值到新值的动画化。这些widget很容易使用,而且功能非常强大。你在上面看到的所有动画都是用隐式动画的widget完成的。隐式动画是一个很好的开始,当你想给某件事情做动画时,隐式动画是一个很好的开始。

显式动画需要一个AnimationController。它们被称为 "显式",因为它们只有在显式要求时才会开始动画化。你可以使用显式动画来做所有你能用隐式动画做的事情,还有更多。恼人的是,你必须手动管理AnimationController的生命周期,因为它不是一个widget,这意味着要把它放在一个有状态的widget里面。基于这个原因,如果你能使用隐式动画widget,你的代码通常会更简单。

有三个问题需要问自己,以确定你需要什么类型的widget。我的动画会永远重复吗?我所说的 "永远 "指的是当它在某个屏幕上时,或者是在某一特定的条件下,如音乐播放时,就会永远重复。

第二个要问自己的问题是你的动画中的值是否是不连续的。我所说的非连续性动画的一个例子是这个不断增长的圆圈动画。这个圆圈反复地变小变大,变小变大。它永远不会变小变大,然后又缩小回来。在这种情况下,圆的大小是不连续的。

一个只会增长,从不缩小的圆圈。这是一个不连续的动画!

最后一个要问自己的问题是,多个widget是否协调地一起动画化?比如说:

多个盒子一起动画化。

如果您对这三个问题中的任何一个回答 "是",您需要使用显式小组件。否則,您可以使用隐式 widget! 一旦您决定了是需要隐式 widget 还是显式 widget,最后一个问题将引导您找到您需要的特定 widget。

哪个widget?

扪心自问,有没有适合我需求的内置 widget?如果你正在寻找一个内置的隐式动画小工具,可以寻找名为AnimatedFoo的小工具,其中 "Foo "是你想要动画化的属性,比如AnimatedOpacity。另外,还可以查看AnimatedContainer,因为它是一个非常强大且用途广泛的小工具,适用于许多不同的隐式动画。

如果你找不到你需要的内置隐式动画,你可以使用TweenAnimationBuilder来创建一个自定义的隐式动画。相反,如果你要找一个内置显式widget,它们通常被称为FooTransition,其中 "Foo "是你要动画的属性,比如SlideTransition。

如果您找不到相关的内置显式动画,还有最后一个问题需要问自己。我想让我的动画成为一个独立的小部件,还是另一个周边的小部件的一部分?这个问题的答案主要是由您的品味决定的。如果你想要一个独立的自定义显式动画,你应该扩展AnimatedWidget。否则,你可以使用AnimatedBuilder。

如果你看到性能问题,还有最后一个选项可以考虑,那就是用CustomPainter做动画。你可以像AnimatedWidget一样使用它,但CustomPainter直接画到Canvas上,没有标准的widget构建范式。如果使用得当,你可以创建一些整齐的、极其自定义的效果或节省性能。但是,如果使用不当,你的动画可能会导致更多的性能问题。所以,要小心谨慎,就像手动内存管理一样,在把共享指针洒得满地都是之前,确保你知道自己在做什么。

结论

总而言之,有一系列高层次的问题,你可以问自己,指导如何创建动画。这一系列的问题会创建一个决策树,以确定什么widget或依赖库适合您的需求。如果你把这些端点折叠成一条线,从左到右大约表示难度。感谢您的阅读,请你去创建伟大的Flutter动画--通过第三方框架,或通过显式或隐式的依赖库来创建伟大的Flutter动画。

动画widget从最简单的...到最难的。


编者注:

mermaid-live-editor

graph TD
  A{Animation} -->|Drawing-Based| b{Design Team}
  b -->|Yes| c[Lottie-Like]
  b -->|No| d[CustomPainter]
  A -->|Code-Based| C{Continuous}
  C -->|Yes| D{Widget}
  D -->|Yes| E[AnimatedFoo]
  D -->|No| F[TweenAnimationBuilder]
  C -->|No| G{FooTransition}
  G -->|Yes| H(explicitly)
  G -->|No| I{standalone}
  I -->|Yes| J[Sub AnimatedWidget]
  I -->|No| K[AnimatedBuilder]