简介
回想一下 Android 的属性动画,我们经常使用的是 ValueAnimator.ofXXX
方法,指定一个起始值,再设定一个耗时,然后系统会根据插值器计算出这段时间内各个时间点内的值。
Flutter 其实也大致一样,AnimationController
默认情况下,会在一个时间段内,线性的生成 0.0~1.0
的数字,也就是说,AnimationController
可以单独的完成一些简单的、数值类的动画效果,如下图:
构造函数
看一下它的构造函数:
AnimationController({
double value,
this.duration,
this.reverseDuration,
this.debugLabel,
this.lowerBound = 0.0,
this.upperBound = 1.0,
this.animationBehavior = AnimationBehavior.normal,
@required TickerProvider vsync,
})
- view,动画的值,该值会随着动画的进度而发生变化
- duration,动画持续时间
- reverseDuration,反向动画的持续时间,如果不设置该值,则反向动画持续时间和正向一样
- debugLabel,可以为动画设置一个标签,调用
AnimationController
的toString()
方法可以输出该标签,用于调试动画时使用 - lowerBound,动画的起始值,默认为 0.0
- upperBound,动画的结束值,默认为 1.0
需要注意,当我们自定义
lowerBound
和upperBound
时,upperBound
必须大于lowerBound
,你想要从大变小,将upperBound
设置小于(或者等于)lowerBound
是不可以的。
- animationBehavior,配置禁用动画时
AnimationController
的行为,详细内容看这里 AnimationBehavior-class vsync
,一个TickerProvider
对象,具体看这里: 动画信号控制 —— Ticker Providers
了解了这些,创建一个 AnimationController
也就不是什么难事儿了。
常用方法
AnimationController
常用方法包括:
animateBack,用于执行当
AnimationController
的value
达到指定值时,进行反向操作例如:controller.addListener(() { if(controller.value > 0.5){ controller.animateBack(0.1,duration: Duration(seconds: 2)); } });
在上面的代码中,当
AnimationController
的value
值逐渐递增直到大于 0.5 时,会在两秒内反向逐渐减小,直到 0.1,然后动画停止。animateTo,将
AnimationController
的value
逐渐过渡到指定值,可以指定过渡时间。注意,该方法中的 target 参数,不能大于 AnimationController 的 upperBound。
animateWith,根据设定的值模拟仿真动画(我个人觉得这个方法以及其参数就是所谓的“物理动画”)
fling,可以根据我们手指滑动(甩出)的速度(velocity)、力量(force)等来模拟一个手指甩出动画,因此它的动画值可以在[0.0,1.0]范围之外,可以实现“物理动画”的效果。
dispose(),停止动画,释放动画资源
forward,开始动画,其参数是动画起始值
repeat,重复动画,其参数中的
min
和max
就是重复的区间stop(),停止动画
reset,重置动画,将动画值设置为 lowerBound 并停止动画
reverse,反向播放动画
status,获取动画的当前状态
注意,一定要记得释放动画资源
状态和监听
Flutter 中动画共分为四个状态,由一个枚举类定义:
enum AnimationStatus {
dismissed,
forward,
reverse,
completed,
}
AnimationController 也提供了一系列方法来监控动画状态:
- isAnimating,动画是否正在运行
- isCompleted,动画是否完成
- isDismissed,动画是否结束
想要获取动画的状态,需要为动画设置监听器:
- addListener,监听动画的值
- removeListener,移除动画监听器
- addStatusListener,监听动画的状态
- removeStatusListener,移除动画状态监听器
示例
看一个简单的例子:
class AnimationRouteState extends State<AnimationRoute>
with TickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
super.initState();
// 创建 AnimationController,用于控制动画
// 必须提供动画时间
animationController = new AnimationController(
lowerBound: 100,
upperBound: 400,
vsync: this,
duration: Duration(milliseconds: 1000));
animationController.addListener(() {
setState(() {});
//当动画执行完成时,动画重复(并反向)
if(animationController.isCompleted){
animationController.repeat(reverse: true);
}
});
// 开始播放动画
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: Container(
width: animationController.value,
color: Colors.lightBlue,
height: animationController.value,
),
),
);
}
@override
void dispose() {
super.dispose();
// 动画使用完成后必需要销毁
animationController.dispose();
}
}
其效果如下: