在 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 了。