在 Flutter 中,動畫被分為兩大類:Tween animation(補間動畫) 和 Physics-based animation(物理動畫)。
Tween animation(補間動畫)
定義了動畫的 初始狀態 和 終止狀態,在指定的一段時間內完成狀態的過度。
期間可以以線性和非線性的方式控制過度的速度。
Physics-based animation(物理動畫)
模擬現實世界物體運動的動畫。比如:自由落體運動、加速度等。
不管是 TweenAnimation 還是 Physics-baseAnimation 最終都是通過計算出一系列的值來修改檢視的屬性,從而讓檢視 "動起來"。
1.一個動畫的例子
class AnimPage2 extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _AnimPage2();
}
}
class _AnimPage2 extends State<AnimPage2> with TickerProviderStateMixin{
var w = 100.0;
var h = 100.0;
Animation<double> animation;
AnimationController animationController;
@override
void initState() {
super.initState();
// 建立 AnimationController,用於控制動畫
// 必須提供動畫時間
animationController = new AnimationController(vsync: this,duration: Duration(milliseconds: 1500));
// 建立一個插值器,關聯 AnimationController,返回一個新的 Animation 物件
animation = Tween<double>(begin: 100.0, end: 100.0*2.0).animate(animationController);
animationController.addListener((){
// 當動畫更新時會呼叫
// 需要在這個函式中,呼叫 setState() 來觸發檢視重新整理
setState(() {
});
});
// 開始播放動畫
animationController.forward();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Anim Demo 2'),
),
body: Container(
alignment: Alignment.center,
child: SizedBox(
// 獲取插值器計算出的 value
// 作為屬性值
width: animation.value,
height: animation.value,
child: Container(
color: Colors.lightBlue,
),
),
),
);
}
@override
void dispose() {
super.dispose();
// 動畫使用完成後必需要銷燬
animationController.dispose();
}
}
複製程式碼
看看效果:
2.動畫中的核心角色
通過觀察上面的例子,可以看出,在 Flutter 中實現動畫效果需要涉及到的幾個核心角色 ?
Animation:動畫物件。
AnimationController:繼承自 Animation,但它能控制動畫的播放、停止等。不需要時必須呼叫
dispose()
釋放掉。Animatable:插值器,用於產生動畫過程中一系列的值。
在 Flutter 中,實現動畫的核心是:
通過 插值器 產生一系列的值;
在值更新的回撥監聽
addListener()
中,通過setState()
重新整理檢視;將 插值器 產生的值設定到相應的檢視屬性上。
3.AnimationController
AnimationController 繼承自 Animation。
就像它的名字一樣,它是動畫的控制器,能夠控制動畫的播放、停止、釋放等。
3.1 AnimationController 常用屬性
屬性 | 型別 | 說明 |
---|---|---|
duration | Duration | 動畫時長 |
lowerBound | double | 設定動畫開始的最小值 |
upperBound | double | 設定動畫結束的最大值 |
vsync | TickerProvider | 用於監聽系統的 Vsync 訊號。當一個 Vsync 資訊發出時,能夠觸發重新整理數值,驅動動畫 |
3.2 AnimationController 常用函式
forward()
開始播放動畫,呼叫它就沒錯了。
stop()
停止動畫。
reset()
重置動畫。
reverse()
反向播放動畫。必須處於正向動畫播放完成的狀態才有用。
dispose()
釋放動畫佔用資源。
fling()
通過內部的 SpringSimulation 產生一系列值來驅動動畫,其值的產生符合 胡克定律。
此時不需要再設定
duration
,設定了也沒用。在建立列表滑動動畫時,你可能會用到它。
這實際上就是一個 Physics-based animation。
repeat()
迴圈播放動畫。
animateWith()
通過 Simulation 來產生值驅動動畫。
3.3 交錯動畫-同時播放多個動畫
在 Flutter 中同時播放多個動畫,只需要使用同一個 AnimationController 就行。
var animationController = new AnimationController(vsync: this,duration: Duration(milliseconds: 1500));
var animation1 = Tween<double>(begin: 100.0, end: 100.0*2.0).animate(animationController);
var animation2 = Tween<double>(begin: 0.0, end: 1.0).animate(animationController);
animationController.forward();
複製程式碼
通過同一個 animationController
物件就可以同時控制 animation1
和 animation2
兩個動畫了。
到此,讀者應該已經能建立自己的動畫 Demo 了。