用一个demo理解一下Flutter动画内部的代码流程
先上代碼:
import 'package:flutter/material.dart';void main() {runApp(MaterialApp(home: Material(child: ScaleAnimationRoute()),),); } //需要繼承TickerProvider,如果有多個AnimationController,則應(yīng)該使用TickerProviderStateMixin。 class _ScaleAnimationRouteState extends State<ScaleAnimationRoute> with SingleTickerProviderStateMixin {Animation<double> animation;AnimationController controller;initState() {super.initState();controller = new AnimationController(duration: const Duration(seconds: 3),vsync: this,);//圖片寬高從0變到300animation = new Tween(begin: 0.0, end: 300.0).animate(controller) //tag0..addListener(() { //tag1setState(() => {});});//啟動動畫(正向執(zhí)行)controller.forward(); //tag2}@overrideWidget build(BuildContext context) {return new Center(child: Image.asset("assets/banner1.png",width: animation.value,height: animation.value,),);}dispose() {//路由銷毀時需要釋放動畫資源controller.dispose();super.dispose();} } 復(fù)制代碼然后上圖:
圖片較大請放大看,然后開始分析:
其中parent是Tween.animate這步傳入的AnimationController,所以執(zhí)行的是AnimationController的addListener方法,所以監(jiān)聽的就是原始發(fā)送動畫數(shù)據(jù)的類實(shí)例,后面不管嵌套多少層動畫,原始數(shù)據(jù)都是從AnimationController這里獲取的值,范圍是0.0-1.0,然后看一下AnimationController這個類:
class AnimationController extends Animation<double>with AnimationEagerListenerMixin, AnimationLocalListenersMixin, AnimationLocalStatusListenersMixin { ... } 復(fù)制代碼省略不相關(guān)代碼,只看繼承結(jié)構(gòu),AnimationController的addListener實(shí)現(xiàn)在父類AnimationLocalListenersMixin里面,所以tag1這步就把值改變時的監(jiān)聽方法保存到了AnimationController類 3. 然后看tag2,調(diào)用AnimationController的forward方法開始動畫后,方法內(nèi)部執(zhí)行_animateToInternal方法,然后animateToInternal內(nèi)部執(zhí)行notifyListeners和_checkStatusChanged遍歷值監(jiān)聽和狀態(tài)監(jiān)聽列表,然后我們的監(jiān)聽方法就被回調(diào)了,我們在回調(diào)里執(zhí)行了setState方法刷新界面,然后在_ScaleAnimationRouteState的build方法里調(diào)用animation.value獲取了變化的值,然后我們分析animation.value這個步驟: 3.1 因?yàn)閍nimation是_AnimatedEvaluation的實(shí)例,所以我們看這個類的內(nèi)部value的方法實(shí)現(xiàn),該方法源碼如下:
@overrideT get value => _evaluatable.evaluate(parent); 復(fù)制代碼其中_evaluatable看tag0這步得知該實(shí)例是Tween,parent是AnimationController實(shí)例, 然后看Tween的內(nèi)部方法_evaluatable
/// The current value of this object for the given [Animation].////// This function is implemented by deferring to [transform]. Subclasses that/// want to provide custom behavior should override [transform], not/// [evaluate].////// See also:////// * [transform], which is similar but takes a `t` value directly instead of/// an [Animation]./// * [animate], which creates an [Animation] out of this object, continually/// applying [evaluate].T evaluate(Animation<double> animation) => transform(animation.value); 復(fù)制代碼Tween的evaluate方法內(nèi)部執(zhí)行transform(animation.value),其中animation是AnimationController,AnimationController的animation的value范圍是0.0-1.0,transform內(nèi)部是實(shí)際將0.0-1.0轉(zhuǎn)換成了對應(yīng)的值,也就是頁面調(diào)用animation(這個是我們的測試代碼的animation,是_AnimatedEvaluation實(shí)例,不要和transform方法里的搞混).value方法后獲得的計(jì)算好的值,可以看一下Tween的transform方法
@overrideT transform(double t) {if (t == 0.0)return begin;if (t == 1.0)return end;return lerp(t);} 復(fù)制代碼分析完了,這就是整個流程,復(fù)雜動畫可能會嵌套多個動畫效果,但是萬變不離其宗,原理都是一樣的,圖片里的[]實(shí)際就是(),但是這個starUML用了小括號后面就不能打字了,所以看的時候不要在這里迷糊就好。
總結(jié)
以上是生活随笔為你收集整理的用一个demo理解一下Flutter动画内部的代码流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Koa与Node.js开发实战(1)——
- 下一篇: nginx 解决session共享问题(