天天看點

Flutter 中的動畫

Flutter 中動畫的建立有很多種, 需要根據具體的需求選擇不同的動畫。如果隻是簡單的布局等的動畫直接使用最簡單的隐式動畫就可以了,因為隐式動畫是由架構控制的,是以僅僅隻需要更改變需要變化屬性就可以了。如果你想自己控制動畫的變換則需要使用顯示動畫,如果需要控制一些列動畫組合時使用交織動畫去控制。如果内置的滿足不了需求的時候,還可以結合畫布自繪動畫。

Flutter動畫和其他平台動畫原理也是一樣的,都是在快速更改UI實作動畫效果。在一個Flutter動畫中主要包含Animation(動畫)、AnimationController(控制器)、Curve(速度曲線)、Animatable(動畫取值範圍)、Listeners (監聽事件)、Ticker(幀)。

Animation 一個抽象類是Flutter動畫的核心類,主用于儲存動畫目前插值的和狀态,在動畫運作時會持續生成介于兩個值之間的插入值。例如當寬從100變成200,會在動畫第一幀到最後一幀都會生成100-200區間的一個值,如果速度是勻速的,這個值就是勻速增加到200。

AnimationController 用來控制動畫的狀态啟動、暫停、反向運作等, 是Animation的一個子類

Curve 用來定義動畫運動的是勻速運動還是勻加速等,和 css 中 animation-timing-function 類似

Animatable 用于表明動畫值範圍值。可以通過調用animate方法,傳回一個Animation,常見的Tween系列的類都是對他的實作

Listener 監聽動畫狀态的變化

Ticker 幀回調,在動畫執行時候每一幀都會調用其回調,類似與 js 中的 requestAnimationFrame

Flutter 中的動畫
Flutter 中的動畫

隐式動畫簡單來說就是我們隻需要修改對應的屬性,Flutter就是自己幫我們過渡動畫,和css中過渡有點類似,當我們設定後transition後隻需要更改對應的css屬性就會自動過渡到新的值。Flutter 内置了一些常用的隐式動畫,可以看到源碼裡都是對ImplicitlyAnimatedWidget的實作,如果需要我們也可以自己實作ImplicitlyAnimatedWidget來自定義隐式動畫。

看個使用例子

在Flutter内置的隐式動畫元件中,一般都是AnimatedXxxxxx類似的,後面的Xxxxxx都能找到對應的元件。内置的有下面這些 AnimatedContainer、AnimatedPadding、AnimatedAlign、AnimatedPositioned、AnimatedOpacity、SliverAnimatedOpacity、AnimatedDefaultTextStyle、AnimatedPhysicalModel。這些隐式動畫的使用和其Xxxxxx對應的屬性基本一緻,隻需要額外的指定 duration 就可以了,當然也可以為動畫指定動畫曲線 curve。

當這内置的滿足不了你的時候,你也可以去實作一個隐式動畫,隻需要實作抽象類 ImplicitlyAnimatedWidget。實作自定義隐式動畫僅需要重寫build 和 forEachTween 就可以簡單實作了。

我們可以去看 ImplicitlyAnimatedWidget 是如何控制動畫的,在 ImplicitlyAnimatedWidgetState 中會看到其實裡面定義了 AnimationController 控制動畫。然後可以看到 didUpdateWidget 鈎子函數中調用了 _controller.forward() 執行動畫,當父 Widget 調用 setState 時候就會觸發這個鈎子函數的調用。

有時候有些動畫需要們自己去控制動畫的狀态,而不是交給架構去處理,這時就需要我們自己去定義前面簡介裡提到的那幾個動畫要素了。

在Flutter中内置的顯示動畫大部分都是XxxxxxTransition名稱的,我們看個内置顯示動畫使用例子,RotationTransition元件需要一個 turns(Animation<double>)參數,我們可以給它個AnimationController

使用 RotationTransition,可以看到一個紅藍漸變色方塊旋轉一周。

在控制器中我們可以看的動畫開始值和結束值預設是0.0到1.0,而且是double類型的。而實際動畫中不可能隻是double類型的,需要我們自己使用Animatable來指定補間範圍值。

修改一下上面的代碼

Flutter已經内置幫我們實作了很多Animatable,ColorTween、SizeTween、IntTween、StepTween等等。

檢視 RotationTransition 的源碼,我們可以看到它是對的抽象類 AnimatedWidget 的實作,當内置的滿足不了我們的時候,可以直接自己實作 AnimatedWidget 自定義顯示動畫。先來看看 AnimatedWidget 裡面都有些啥。

接下來我自己繼承 AnimatedWidget 實作一個自定義顯示動畫

Flutter 内部還提供了一個 AnimatedBuilder 幫助我們簡化自定義動畫。

官方是這麼介紹的:交織動畫是一個簡單的概念:視覺變化是随着一系列的動作發生,而不是一次性的動作。動畫可能是純粹順序的,一個改變随着一個改變發生,動畫也可能是部分或者全部重疊的。動畫也可能有間隙,沒有變化發生。

簡單點說就是一個動畫可以分割成很多片段,每個片段都有不同的Tween,看個使用示例

Flutter叫它主動畫,用于不同頁面之間切換時候動畫,比如有一個商品清單,點選後跳到一個新的頁面檢視原圖,就可以這個動畫。使用也很簡單,在不同頁面使用Hero包裹需要動畫元件,兩個頁面的 tag 需要甚至成一直,但是同一個頁面需要保持唯一。