携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
本文主要介绍下动画类AnimationController的使用
动画是通过把人物的表情、动作、变化等分解后画成许多动作瞬间的画幅,再用摄影机连续拍摄成一系列画面,给视觉造成连续变化的图画。它的基本原理与电影、电视一样,都是视觉暂留原理。
医学证明人类具有“视觉暂留”的特性,人的眼睛看到一幅画或一个物体后,在0.34秒内不会消失。利用这一原理,在一幅画还没有消失前播放下一幅画,就会给人造成一种流畅的视觉变化效果。
我们在flutter中使用简单的动画效果放大
Scaffold(
appBar: AppBar(title: const Text(''),),
body:Center(
child: ElevatedButton(
onPressed: () {
setState(() {
_size = 200;
});
},
child: Icon(Icons.add,size: _size,)
),
) ,
)
虽然是变大了,但并没有什么动画效果,比较突兀,想要使其一点点放大需要引入 AnimationController,它是动画控制器,控制动画的启动、停止,还可以获取动画的运行状态,AnimationController 通常在 initState 方法中初始化:
class _AnimationCorePageState extends State<AnimationCorePage> with SingleTickerProviderStateMixin {
double _size = 100;
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this,duration: Duration(milliseconds: 500));
}
这里有两个参数需要设置:
- vsync:当创建 AnimationController 时,需要传递一个
vsync参数,存在vsync时会防止屏幕外动画消耗不必要的资源,单个 AnimationController 的时候使用 SingleTickerProviderStateMixin,多个 AnimationController 使用 TickerProviderStateMixin。 - duration:表示动画执行的时间。
onPressed: () {
_controller.forward();
}
点击的时候不直接修改size,而是执行动画_controller.forward()。我们对AnimationController添加监听,发生变化的时候改变size
_controller = AnimationController(vsync: this,duration: const Duration(milliseconds: 500));
_controller.addListener(() {
setState(() {
_size = 100+100*_controller.value;
});
});
_controller.value 是当前动画的值,默认从 0 到 1。也可以通过参数形式设置最大值和最小值:
_controller = AnimationController(vsync: this,duration: const Duration(milliseconds: 500),lowerBound: 100,upperBound: 200);
_controller.addListener(() {
setState(() {
_size = _controller.value;
});
});
动画的状态分为四种:
- dismissed:动画停止在开始处。
- forward:动画正在从开始处运行到结束处(正向运行)。
- reverse:动画正在从结束处运行到开始处(反向运行)。
- completed:动画停止在结束处。
动画的控制方法:
- forward:正向执行动画。
- reverse:反向执行动画。
- repeat:反复执行动画。
- reset:重置动画。
监听动画的状态
_controller.addStatusListener((status) {
if(status == AnimationStatus.completed){
_controller.reverse();
}else if(status == AnimationStatus.dismissed){
_controller.forward();
}
});
只需监听动画状态变化,在动画结束后再正向/反向再次执行动画。