天天看點

Flutter 動畫

flutter動畫中有4個比較重要的角色:animation、controller、curve、tween,先來了解一下這四個角色

animation是flutter動畫庫中的核心類,用于插入指導動畫的值

animation對象知道動畫目前的狀态(比如開始還是停止),可以使用addlistener和addstatuslistener監聽動畫狀态改變。

addlistener: 每一幀都會調用,調用之後一般使用setstate來重新整理界面

addstatuslistener:監聽動畫目前的狀态 如動畫開始、結束、正向或反向

在flutter中,animation對象本身和ui渲染沒有任何關系。animation是一個抽象類,它擁有其目前值和狀态(完成或停止)。其中一個比較常用的animation類是 animation<double> ,還可以生成除double之外的其他類型值,如: animation<color> 或 animation<size> 。

用來管理animation,它繼承自animation, 是個特殊的animation ,螢幕每重新整理一幀,它都會生成一個新值,需要一個vsync參數, vsync的存在可以防止背景動畫消耗不必要的資源 。

vsync的值怎麼獲得,可以讓stateful對象擴充使用tickerproviderstatemixin比如:

animationcontroller在預設情況下,在給定的時間段内,animationcontroller會生成0.0到1.0的數字。

它可以控制動畫,比如使用 .forward() 方法可以啟動一個動畫, .stop() 可以結束一個動畫, .reverse() 啟動反向動畫。

看一下animationcontroller的構造方法,有一個必須的參數tickerprovider,就是前面給定的tickerproviderstatemixin

在statefulwidget中建立一個animationcontroller對象

定義動畫曲線,運動過程,比如勻速,先加速在減速等等

它有兩個必要的參數parent和curve。parent就是前面的animationcontroller對象,curve就是動畫運作的曲線,相當于android屬性動畫中的插值器curve都有哪些取值呢

linear|勻速的

decelerate|勻減速

ease|先加速後減速

easein|開始慢後面快

easeout|開始快後面慢

easeinout|先慢在快在慢

上面是常用的一些曲線,還有很多中曲線運動的方式可以去curve.dart源碼中去看,源碼注釋中有mp4的連結,可以清楚的看到動畫運動的視訊。

如果系統提供的運動曲線仍然無法滿足我們的需求,那就可以繼承curve來自己實作一個。上面的代碼可以看到curve是一個抽象類,繼承它并重寫transform方法即可。比如我們可以自己在裡面實作一個sin或者cos函數的曲線。例如

建立一個curvedanimation對象

給動畫對象插入一個範圍值

預設情況下,animationcontroller對象的範圍從0.0到1.0,如果我們想要更大的範圍,就需要使用到tween了。比如

class tween<t extends dynamic> extends animatable<t> tween繼承自animatable,接收一個begin和一個end值,tween的職責就是定義從輸入範圍到輸出範圍的映射。是以這兩個值必須能進行加減乘的運算。

要使用tween對象,調用其animate()方法,傳入一個控制器對象,傳回一個animation對象。例如,

動畫的四個角色都了解了,下面開始使用這些角色來建構一個動畫,動畫效果如下圖

Flutter 動畫

有一個心形的button,點選的時候放大并且顔色漸變,在點選的時候原路傳回

2.1中每次寫動畫都需要在addlistener中設定setstate來更新ui,有點麻煩,系統給提供了一個animatedwidget,它内部封裝了addlistener和setstate的邏輯,我們隻需要傳給它animationcontroller和animation就行了。

而且我們可以自定義一個widget繼承它,讓動畫跟原來的視圖代碼分離

自定義一個animationheart繼承自animatedwidget,在構造方法中将animationcontroller和animation傳過來。其餘的跟2.1中一樣,最終效果也一樣。

flutter中還可以使用animatedbuilder來建構一個動畫

執行個體化四個動畫元素的代碼跟前面還是一樣,主要是在build代碼塊中使用animatedbuilder建構,傳入animation對象。看起來比2.2中的方式也沒有簡單多少,不過看一下它的構造方法,系統還給提供了一個可選的參數child,讓它天然就支援封裝。

必需要一個listenable,animation就是listenable

必需要一個builder,前面的代碼中知道builder中需要傳一個context和一個child

可以傳一個child。 傳入的這個child最終會傳入到builder中

上面的例子中我們是直接在builder中建立了一個控件,既然child可以傳進來,那麼我們可以把一個類型的動畫封裝一下比如縮放動畫,漸變動畫等,以後隻要把需要此動畫的小部件傳進來,這個小部件就有這個動畫了。

比如下面定義一個可以縮放的小部件。

hero動畫很簡單不過在平時的項目中也經常用到,主要用在路由頁面之間切換。比如一個頭像點選看大圖,或者新聞清單頁面,點選看詳情,這種共享式的無縫切換。

動畫效果如下圖

Flutter 動畫

目前頁面的圓形小圖和詳情頁面的大圖都使用hero包裹。

必須使用相同的tag,flutter framework通過tag來确定他們之間的關系。

有時候我們需要實作一組複雜的動畫,比如在0.1-0.2秒縮放,從0.2-0.4秒顔色漸變,從0.4-0.8秒左右移動,這時候使用交織動畫可以友善的完成,使用交織動畫需要注意下面幾點

需要使用多個animation對象

一個animationcontroller控制所有的動畫對象

給每一個動畫對象指定時間間隔(interval)

staggeranimation中定義了5個動畫,寬,高,顔色,左邊距,圓角

使用interval來定義某個動畫執行的時機

最後異步啟動動畫。

上一篇: Flutter 簡介
下一篇: 5個數求最值