在 Flutter 中,動畫被分爲兩大類:Tween animation(補間動畫) 和 Physics-based animation(物理動畫)。github
Tween animation(補間動畫)bash
定義了動畫的 初始狀態 和 終止狀態,在指定的一段時間內完成狀態的過分。app
期間能夠以線性和非線性的方式控制過分的速度。ide
Physics-based animation(物理動畫)函數
模擬現實世界物體運動的動畫。好比:自由落體運動、加速度等。post
無論是 TweenAnimation 仍是 Physics-baseAnimation 最終都是經過計算出一系列的值來修改視圖的屬性,從而讓視圖 "動起來"。動畫
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();
}
}
複製代碼
看看效果:ui
經過觀察上面的例子,能夠看出,在 Flutter 中實現動畫效果須要涉及到的幾個核心角色 🎭this
Animation:動畫對象。
AnimationController:繼承自 Animation,但它能控制動畫的播放、中止等。不須要時必須調用 dispose()
釋放掉。
Animatable:插值器,用於產生動畫過程當中一系列的值。
在 Flutter 中,實現動畫的核心是:
經過 插值器 產生一系列的值;
在值更新的回調監聽 addListener()
中,經過 setState()
刷新視圖;
將 插值器 產生的值設置到相應的視圖屬性上。
AnimationController 繼承自 Animation。
就像它的名字同樣,它是動畫的控制器,可以控制動畫的播放、中止、釋放等。
屬性 | 類型 | 說明 |
---|---|---|
duration | Duration | 動畫時長 |
lowerBound | double | 設置動畫開始的最小值 |
upperBound | double | 設置動畫結束的最大值 |
vsync | TickerProvider | 用於監聽系統的 Vsync 信號。當一個 Vsync 信息發出時,可以觸發刷新數值,驅動動畫 |
forward()
開始播放動畫,調用它就沒錯了。
stop()
中止動畫。
reset()
重置動畫。
reverse()
反向播放動畫。必須處於正向動畫播放完成的狀態纔有用。
dispose()
釋放動畫佔用資源。
fling()
經過內部的 SpringSimulation 產生一系列值來驅動動畫,其值的產生符合 胡克定律。
此時不須要再設置 duration
,設置了也沒用。
在建立列表滑動動畫時,你可能會用到它。
這實際上就是一個 Physics-based animation。
repeat()
循環播放動畫。
animateWith()
經過 Simulation 來產生值驅動動畫。
在 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 了。