剛剛看了一下flutter的路由動畫文檔,地址是:page-route-animation html
PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => Page2(), transitionsBuilder: (context, animation, secondaryAnimation, child) { var begin = Offset(0.0, -1.0); var end = Offset.zero; var curve = Curves.ease; var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition( position: animation.drive(tween), child: child, ); }, ) 複製代碼
針對動畫,學習了兩點:api
1. 頁面顯示在屏幕時,Offset的dx dy均爲0;
2. 若是須要動畫頁面從屏幕底部彈出,則應該是dy=1 到 dy=0;
3. 若是須要動畫頁面從右側推入到屏幕,則應該是dx=1 到 dx=0;
4. 若是須要動畫頁面從屏幕頂部彈出,則應該是dy=0 到 dy=-1
5. 其餘相似
複製代碼
建議你們使用文檔裏的案例操做實驗一下,加深印象。學習了這個,在寫動畫時就不會出現亂套的狀況了。bash
寫過安卓的都清楚有進場和出場動畫,overridexxxx,那flutter只經過上面這段代碼怎麼實現出場,就給了一個child,非常奇怪。而後我發現secondaryAnimation還沒用,是幹嗎的?翻閱的一些文檔: buildTransitionsmarkdown
看到了使用方式:ide
transitionsBuilder: ( BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child, ) { return SlideTransition( position: AlignmentTween( begin: const Offset(0.0, 1.0), end: Offset.zero, ).animate(animation), child: SlideTransition( position: TweenOffset( begin: Offset.zero, end: const Offset(0.0, 1.0), ).animate(secondaryAnimation), child: child, ), ); } 複製代碼
剛看到我是很驚訝的,這是個怎麼操做法?進出都套在了一個child上,到底怎麼運行的呢?一開始我猜測難道是源碼使用的地方會取出child的child?看了源碼後,我以爲設計真巧妙!!oop
首先介紹下這兩個動畫常量(animation.dart中,目的就是保持動畫終止位置和保持動畫起始位置):學習
kAlwaysCompleteAnimation // The animation is stopped at the end
測試
kAlwaysDismissedAnimation // The animation is stopped at the beginning
動畫
看到這裏你們可能會有點明白了,兩個animation是否是用上面兩個常量,來切換使用作到每次只運行一個的呢?ui
而後我用下面的動畫(一段動畫,新頁面從右側屏幕滑入,舊頁面從屏幕左側滑出),打印了一下對應的回調:
SlideTransition( position: Tween<Offset>( begin: const Offset(1.0, 0.0), end: Offset.zero, ).animate(animation), child: SlideTransition( position: Tween<Offset>( begin: Offset.zero, end: const Offset(-1.0, 0.0), ).animate(secondAnimation), child: child, ), ) 複製代碼
獲得的log,簡化後:
animation | sencondaryAnimation |
---|---|
AnimationController#1c77c(▶ 0.335 | kAlwaysDismissedAnimation |
AnimationController#fc1fe(⏭ 1.000 | AAnimationController#1c77c(▶ 0.335 |
AnimationController#1c77c(▶ 0.535 | kAlwaysDismissedAnimation |
AnimationController#fc1fe(⏭ 1.000 | AAnimationController#1c77c(▶ 0.535 |
AnimationController#1c77c(⏭ 1.000 | kAlwaysDismissedAnimation |
AnimationController#fc1fe(⏭ 1.000; | AnimationController#1c77c⏭ 1.000 |
先只看#1c77c這個animation:
發現第一個參數是從0-1作的動畫,第二個參數是保持不變在start狀態即Offset.zero
,即經過改變第一個widge的位置,來實現界面從右側滑入,第二個widget一直保持可見狀態。
再來看下fc1fe這個animation,發現這個動畫是第一個widge保持在end狀態即Offset.zero
(屏幕上),第二個動畫是從0-1運行,即offset.dx從0 -> -1,也就是頁面從屏幕往左側滑出的動畫。
由以上,咱們能夠得出結論,animation參數值是用來給新push的頁面作進場動畫的,secondaryAnimation是給前頁面作出廠動畫的,靈活運用兩個動畫的變化值來實現動畫,參數只須要一個child便可,我也從中學習了一種新的思路,建議你們也測試感覺下。