在Flutter中,Animation对象本身和UI渲染没有关系,它是一个抽象类,拥有当前值和状态。并且有一个泛型,常用的是Animation
。
Flutter中Animation对象是一个在一段时间内依次生成一个区间之间值的类输出的值可以是线性的、曲线的或者一个任意函数。根据Animation对象的控制方式,动画可以反向运行,甚至可以在中间切换方向。
Animation
、Animation
等;AnimationController
是一个特殊的Animation
对象,在屏幕刷新的每一帧,就会生成一个新的值。默认情况下,AnimationController
在给定的时间段会线性的生成0.0到1.0的数字。例如:
final AnimationController controller = new AnimationController(duration:const Duration(milliseconds:2000),vsync:this);
AnimationController
派生自Animation
,因此可以再需要Animation对象的任何地方使用。但是,AnimationController
常用方法:
forward()
:启动动画;reverse()
:倒放动画;reset()
:重置动画,将其设置到动画的开始位置;stop()
:停止动画;默认情况下,AnimationController对象的范围从0.0到1.0.如果需要不同范围,可以设置:
final Tween tween = Tween
Tween继承了Animatable
。Animatable与Animation相似,不是必须输出double值。例如,ColorTween可以指定两种颜色之间的过渡。
final Tween colorTween = ColorTween(begin: Colors.red, end: Colors.blue);
Tween对象不存储任何状态。它提供了evaluate(Animation
方法将映射函数应用于动画当前值。Animation对象的当前值可以通过value()
获取。evaluate方法还执行了一些其他处理,例如分别确保在动画值为0.0和1.0时返回开始和结束状态。
Tween.animate
要使用Tween对象,可调用它的animate()方法,传入一个控制器。例如:
final AnimationController controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
Animation<int> tween = IntTween(begin: 0, end: 255).animate(controller);
animate()
返回一个Animation.
结合CurvedAnimation使用:
final AnimationController controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
final Animation<double> curve =
CurvedAnimation(parent: controller, curve: Curves.easeOut);
Animation<int> tween = IntTween(begin: 0, end: 255).animate(curve);
如果需要知道动画执行的进度和状态,可以通过Animation的addListener
和addStatusListener
方法给动画添加监听器:
class LogoAnimation extends StatefulWidget {
const LogoAnimation({Key? key}) : super(key: key);
State<LogoAnimation> createState() => _LogoAnimationState();
}
class _LogoAnimationState extends State<LogoAnimation>
with SingleTickerProviderStateMixin {
Animation<double>? animation;
AnimationController? controller;
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
animation = Tween(begin: 0.0, end: 200.0).animate(controller!)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller!.reverse();
} else if (status == AnimationStatus.dismissed) {
controller!.forward();
}
})
..addListener(() {
setState(() {});
});
controller!.forward();
}
void dispose() {
controller?.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('动画'),
),
body: Center(
child: Container(
height: animation?.value,
width: animation?.value,
child: const FlutterLogo(),
),
),
);
}
}
AnimatedWidget
可以将AnimatedWidget理解为Animation的助手,使用它可以简化对动画的使用,在不使用AnimatedWidget的情况下需要手动调用动画的addListener()并在回调中添加setState才能看到动画的效果,AnimatedWidget简化了这一操作。
AnimatedBuilder
AnimatedBuilder是用于构建动画的通用widget,AnimatedBuilder对于希望将动画作为更大构建函数的一部分包含在内的更复杂的widget时,非常适用。其实AnimatedBuilder是拆分动画的一个工具类,适用它可以将动画和widget进行解耦分离。