在之前的学习中,学会了如何给一个 Widget 设置一个简单的动画,但如果动画效果很复杂呢?
例如一个 Widget 在变换大小的同时改变颜色或者改变形状?
我们只需要把复杂动画分解成若干个简单动画,然后分别实现,最后组合在一起执行即可。
看例子:
void main() {
runApp(MaterialApp(home: GroupAnimation()));
}
class GroupAnimation extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return GroupAnimationState();
}
}
class GroupAnimationState extends State<GroupAnimation>
with TickerProviderStateMixin {
AnimationController controller;
Animation<Color> colorAnimation;
Animation<double> sizeAnimation;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(seconds: 3));
CurvedAnimation curvedAnimation =
CurvedAnimation(parent: controller, curve: Curves.easeIn);
colorAnimation = ColorTween(begin: Colors.red, end: Colors.lightGreen)
.animate(curvedAnimation);
sizeAnimation =
Tween<double>(begin: 100, end: 400).animate(curvedAnimation);
controller.addListener(() {
if(controller.isCompleted){
controller.repeat(reverse: true);
}
});
controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("组合动画"),
),
body: GroupAnimationWidget(
animation: colorAnimation,
colorAnimation: colorAnimation,
sizeAnimation: sizeAnimation,
),
);
}
@override
void dispose() {
super.dispose();
// 动画使用完成后必需要销毁
controller.dispose();
}
}
class GroupAnimationWidget extends AnimatedWidget {
GroupAnimationWidget(
{Key key,
Animation<Color> animation,
Animation<Color> colorAnimation,
Animation<double> sizeAnimation})
: super(key: key, listenable: animation) {
this.colorAnimation = colorAnimation;
this.sizeAnimation = sizeAnimation;
}
Animation<Color> colorAnimation;
Animation<double> sizeAnimation;
@override
Widget build(BuildContext context) {
Animation<Color> animation = listenable;
return Container(
color: colorAnimation.value,
width: sizeAnimation.value,
height: sizeAnimation.value,
);
}
}
效果如下:
代码很简单,就不解释了。
再设想一下,我们想要动画先变色,再变形,这该怎么办呢?
还记得之前的 Curve 的子类不,用在这里不是正合适么,废话不多说,看代码:
void main() {
runApp(MaterialApp(home: GroupAnimation()));
}
class GroupAnimation extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return GroupAnimationState();
}
}
class GroupAnimationState extends State<GroupAnimation>
with TickerProviderStateMixin {
AnimationController controller;
Animation<Color> colorAnimation;
Animation<double> sizeAnimation;
@override
void initState() {
super.initState();
//定义共耗时 4 秒
controller =
AnimationController(vsync: this, duration: Duration(seconds: 4));
//0.0~0.8 执行该 Tween,也就是前 3.2 秒是变色
colorAnimation = ColorTween(begin: Colors.red, end: Colors.lightGreen)
.animate(CurvedAnimation(
parent: controller,
curve: Interval(0.0, 0.8, curve: Curves.easeIn)));
//0.8~1.0 执行该 Tween,也就是后 0.8 秒是变形
sizeAnimation =
Tween<double>(begin: 100, end: 400).animate(CurvedAnimation(
parent: controller,
curve: Interval(0.8, 1.0, curve: Curves.easeIn)));
controller.addListener(() {
if(controller.isCompleted){
controller.repeat(reverse: true);
}
});
controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("组合动画"),
),
body: GroupAnimationWidget(
animation: colorAnimation,
colorAnimation: colorAnimation,
sizeAnimation: sizeAnimation,
),
);
}
@override
void dispose() {
super.dispose();
// 动画使用完成后必需要销毁
controller.dispose();
}
}
class GroupAnimationWidget extends AnimatedWidget {
GroupAnimationWidget(
{Key key,
Animation<Color> animation,
Animation<Color> colorAnimation,
Animation<double> sizeAnimation})
: super(key: key, listenable: animation) {
this.colorAnimation = colorAnimation;
this.sizeAnimation = sizeAnimation;
}
Animation<Color> colorAnimation;
Animation<double> sizeAnimation;
@override
Widget build(BuildContext context) {
return Container(
color: colorAnimation.value,
width: sizeAnimation.value,
height: sizeAnimation.value,
);
}
}
效果如下:
注释也写的很清楚了,就不赘述了。
官方给了两个复杂一些的例子,但套路是一样的,可以看一下: