本文翻译自
原文地址:How to Choose Which Flutter Animation Widget is Right for You?
原作者:Andrew Fitz Gibbon
如果想要看这篇文章的视频的话,点击这里YouTube video
本文最初由Emily Fortuna撰写,并已以她的名义发布。
好了,你已经决定了在Flutter中使用动画--多么令人兴奋。问题是,有很多不同的动画widget,想要找出用哪一个最合适也是令人不知多措的。幸运的是,本文将会有所帮助。
你也可以在脑海里回顾自己有关于动画的考虑,我也将通过一系列问题帮助你决定如何创建动画。另一件需要记住的事是,Flutter核心库中提供的动画相对来说更底层偏基础,这意味着如果你想要更复杂的动画,我建议你先在Pub.Dev上查找看看有没有可用的动画库,这些库提供更高级的封装。
看一下下面的决策树,我将在本文进行解释。
总的来说,你可能希望在你的Flutter APP中包含两种主要的动画类型:基于绘制(drawing-based)的动画和基于代码(code-based)的动画。
基于代码的动画以Widget为关注点,并植根于标准布局和样式,比如rows, columns, colors, 或者 text styles,并不是说它们无聊或者简单,而是从本质上讲,它们倾向于改变现有存在Widget的外观或过渡效果,而不是自己作为独立小组件。
相反基于绘制的动画,看起来就像有人在绘制他们,他们经常是独立的Spirit,像游戏角色,或者涉及到通过代码表达很难进行转换。
因此第一个问题是:"我的动画更像绘制,还是看起来可以通过Flutter的基础组件进行构建?",如果你的动画更像是绘制,或者你正在和可以提供矢量或光栅图表资源的设计团队一起工作,那么建议您使用三方工具(比如Rive 或 Lottie)以图形的方式构建动画,然后导出到Flutter,有几个package可以帮助您将这些资源应用到你的Flutter APP中。
另一方面,如果您的动画包只含Widget属性转变--比如改变颜色、形状、位置--你可以只写一些Flutter代码就可以实现。
显式还是隐式?
基于Flutter代码的动画也有两种类型:隐式和显式动画,接下来是弄清你需要哪种类型。
当值改变时,隐式动画Widget会触发动画
隐式动画只需要简单地为某些widget设置一个新值,Flutter就会将其从当前值动画化为新值。这些widget很容易使用、功能强大。您在上图中看到的所有动画都是通过隐式动画widget完成的,隐式动画是在制作动画时首先应该考虑的。
显式动画需要一个AnimationController
,它们被称之为”显式“,是因为它们仅在明确要求开始时才开始动画,你能用显式动画做到隐式动画能做的任何效果,并且能做更多的事情。代价就是你需要手动的管理AnimationController
的生命周期,因为它不是一个Widget,因此意味着需要将其放到stateful widget中使用。也是由于这些原因,如果同样的功能使用隐式动画Widget,开发起来代码量会少更简单。
显示还是隐式?有三个问题你需要问你自己,以确定你需要哪种类型的widget:"我的动画会永远重复吗?",”永远“想表达的意思是,当它在某个屏幕上的时候,或者只要判断条件为真,比如音乐播放时。
第二个问题是:"动画中改变的值是否是不连续的?",举一个我说的不连续的例子,如下图中增长的圆形动画,圆圈重复的从小变大、从小变大,它不会从小变大,然后再收缩,这种例子中,圆圈的大小是不连续的。
一个只会变大不会缩小的圆圈,这是一个不连续的动画
最后一个问题需要问你自己的是:"是否有多个Widget以协调的方式一起动画?",例如下图中的多个盒子一起动画
如果您对这三个问题的任何一个回答”是“,那么你需要使用显式Widget,否则您可以使用隐式Widget!一旦确定使用显式还是隐式Widget,最后一个问题将会引导你找到民所需要的特定Widget。
使用哪一个Widget?
问问自己,"是否有满足我需求的内置Widget?",如果你想寻找内置隐式动画Widget,请查找名为AnimatedFoo
的Widget,”FOO“是要设置的动画属性,例如AnimatedOpacity,此外还可以检查AnimatedContainer,对于许多不同的隐式动画来说,它是一个非常强大和通用的小部件。
如果找不到你要要的内置隐式动画,可以使用TweenAnimationBuilder创建一个自定义的隐式动画。相反如果你正在寻找内置显示动画,它们通常被称为FooTransition
,其中”FOO“是您想要设置的动画属性,例如SlideTransition。
如果找不到相关的内置显示动画,则您需要问自己最后一个问题:"我希望我的动画称为独立的Widget,还是希望成为周围Widget的一部分?",这个问题的答案主要取决于你的想法,如果你想要自定义独立的显示动画,你应该继承自AnimatedWidget,否则你可以使用AnimatedBuilder。
如果您关心性能问题,还有最后一个选择需要考虑,那就是使用CustomPainter
进行动画。你可以像使用AnimatedWidget那样使用它,不同的是CustomPainter是直接绘制在Canvas上,无需标准的Widget构建范例。如果使用得当,你可以创建一些整洁、完全自定义的效果或者节省性能,如果错用,你的动画将会导致更多的性能问题。因此要小心,就像手动内存管理一样,确保将共享指针散布到各处之前,你知道自己都在做什么。
结论
总之,可以问自己一系列高层次的问题,以指导你如何创建动画。基于这些问题的顺序创建了决策树,来决定哪种Widget更适合你的需要。如果决策树的终点折叠起来,它们将落成一条线,大约从左到右递增的难度,感谢您阅读本文,并继续创建Flutter动画,无论是通过三方框架,package或者是显式的隐式的动画。
系列文章: