Staggered Animations
Staggered Animations就是交错动画,也可以称之为组合动画。在实际的动画使用过程中,动画可能并不是由一个单一方式呈现的。渐变,位移,缩放等都是基础的动画,而我们有时候需要把这些基础的动画组合起来,使其成为一个组合动画,即交错动画。(下图为本文最终实现效果)
在Android开发中,是通过AnimationController来实现这种交错动画的。在Flutter开发中,也沿用了名为AnimationController的类来实现。
组合动画的代码实现
对于如何在Flutter开发中,写交错动画,我们可以通过AnimationController把动画组合在一起,然后分别设置其动画的参数即可。
对于AnimationController来说,控制器的值Tween必须属于(0.0,1.0)。也就是说,组合动画的所有间隔必须在0到1的数字之间进行,有了这个思路,我们来实践实现其交错动画(组合动画),代码如下:
import 'package:flutter/scheduler.dart' show timeDilation; class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{ AnimationController controller; @override void initState() { // TODO: implement initState super.initState(); controller=AnimationController(duration: const Duration(milliseconds: 2000),vsync: this);//初始化,动画控制器,每个动画都是执行2秒 } @override void dispose() { // TODO: implement dispose super.dispose(); controller.dispose();//销毁释放 } Future<void> _playAnimation() async{ try{ await controller.forward().orCancel;//开始 await controller.reverse().orCancel;//反向 }on TickerCanceled{ } } @override Widget build(BuildContext context) { timeDilation=10.0; return Scaffold( appBar: AppBar( title: Text("组合动画"), ), body: GestureDetector( behavior: HitTestBehavior.opaque,//自己处理事件 onTap: (){ _playAnimation(); }, child: Center( child: Container( width: 300.0, height: 300.0, decoration: BoxDecoration( color: Colors.black.withOpacity(0.1), border: Border.all( color: Colors.black.withOpacity(0.5), ), ), child: StaggedAnimation(controller: controller.view,), ), ), ), ); } } class StaggedAnimation extends StatelessWidget{ //Curves.ease一种三次动画曲线,速度快,结束慢 final Animation<double> controller; final Animation<double> bezier;//透明度渐变 final Animation<double> width;//宽度变化 final Animation<double> height;//高度变化 final Animation<EdgeInsets> drift;//位移变化 final Animation<BorderRadius> borderRadius;//圆角变化 final Animation<Color> color;//颜色变化 StaggedAnimation({Key key,this.controller}): bezier=Tween<double>( begin: 0.0, end: 1.0, ).animate( CurvedAnimation( parent: controller, curve: Interval(0.0, 0.1,curve: Curves.ease), ) ), width=Tween<double>( begin: 50.0, end: 150.0, ).animate( CurvedAnimation( parent: controller, curve: Interval(0.125,0.250,curve: Curves.ease), ) ), height=Tween<double>( begin: 50.0, end: 150.0, ).animate( CurvedAnimation( parent: controller, curve: Interval(0.250,0.375,curve: Curves.ease), ), ), drift=EdgeInsetsTween( begin: const EdgeInsets.only(bottom: 16.0), end: const EdgeInsets.only(bottom: 75.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.375,0.5,curve: Curves.ease), ), ), borderRadius=BorderRadiusTween( begin: BorderRadius.circular(4.0), end: BorderRadius.circular(75.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.5,0.75,curve: Curves.ease), ), ), color=ColorTween( begin: Colors.indigo[100], end: Colors.orange[400], ).animate( CurvedAnimation( parent: controller, curve: Interval(0.75,1.0,curve: Curves.ease), ), ), super(key:key); Widget _buildAnimation(BuildContext context,Widget child){ return Container( padding: drift.value, alignment: Alignment.bottomCenter, child: Opacity(//透明组件 opacity: bezier.value, child: Container( width: width.value, height: height.value, decoration: BoxDecoration( color: color.value, border: Border.all( color: Colors.indigo[300], width: 3.0 ), borderRadius: borderRadius.value, ), ), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: _buildAnimation, animation: controller, ); } }
上面代码使用的是AnimatedBuilder,这样可以不用去显式的去添加addlistener,节省很多代码,不懂的可以回顾前面的内容,其他的代码不用多说,还有,dart异步在第三篇dart语言中有讲到,这里就不过多的赘述了,这段组合动画实现的效果如首图所示。