flutter第四篇:学习大地老师《Flutter入门实战系列视频教程》笔记下
flutter中的动画主要分为隐式动画、显式动画、自定义隐式动画、自定义显式动画、Hero动画5种。
隐式动画:Animatedxxx
AnimatedContainer,当容器属性改变时,触发动画。
AnimatedPadding,当padding值改变时,触发动画。
AnimatedPositioned,当position的位置改变时,触发动画。
AnimatedOpacity,当透明度改变时,触发动画。
AnimatedDefaultTextStyle,当TextStyle的属性改变时,触发动画。
AnimatedSwitcher,当其子元素改变时,触发动画。
隐式动画,在触发时需要调用setState(),让State的build()方法重新执行。
自定义隐式动画:
使用TweenAnimationBuilder。tween属性赋值为一个Tween实例,duration指定动画执行时间,builder属性指定一个返回Widget的函数,函数第二个参数是Tween实例中指定的从begin变到end的值,我们在构造Widget时使用这个值,从而实现动画。函数的第三个参数是用于性能优化的,如果我们返回的Widget有child,那么可以把TweenAnimationBuilder的child属性赋值为此child,即在此构造,这样第三个参数就是这个child了,在构造Widget时就可以把第三个参数直接赋值给Widget的child属性,这样虽然执行动画过程中builder函数会多次执行,但是child不会多次构造。
显式动画:xxxTransition。要用到AnimationController。
RotationTransition,让元素旋转。child属性是普通元素,turns属性是一个AnimationController实例。通过调用这个AnimationController实例的repeat()方法可以让元素一直旋转,调用forward()方法可以让元素顺时针旋转一圈,调用reverse()方法可以让元素逆时针旋转一圈,调用reset()方法可以让元素重置到初始角度,调用stop()方法可以让元素停止旋转。AnimationController构造方法必须指定vsync属性,值是一个TickerProvider实例,我们让xxxState with SingleTickerProviderStateMixin,然后传this即可。还必须指定duration属性,值是一个Duration实例,表示动画执行的时间,不传的话,虽然编译时不会报错,但动画执行时会报错。
FadeTransition,改变元素的透明度。opacity属性是一个Animation<double>实例,用AnimationController实例。
ScaleTransition,对元素进行缩放。scale属性是一个Animation<double>实例,用AnimationController实例。
SlideTransition,对元素进行位移。position属性是一个Animation<Offset>实例,调用Tween实例的animate()方法赋值。Tween(begin: Offset(0, 0), end: Offset(0.2, 0.2)).animate(controller)。第一个0.2表示向右移0.2*(元素的宽度),第二个0.2表示向下移动0.2*(元素的高度)。
AnimatedIcon,改变图标,由一个图标变为另一个图标。
显式动画,在触发时不需要调用setState()。
自定义显式动画:
使用AnimatedBuilder。animation属性赋值为一个AnimationController实例,builder属性指定一个返回Widget的函数。在构造Widget时,用到controller.value,或者用到controller.drive(Tween(begin: a, end: b)).value,这个value是动态变化的,从而实现动画效果。builder函数的第二个参数和自定义隐式动画中builder函数的第三个参数用法和作用一样。如我们想改变Container的透明度,则可以用Opacity包裹Container,builder返回Opacity,Opacity的opacity属性值用到controller.value。如我们想让Container进行位移,则可以让Container的transform属性用到controller.value。
交错动画
交错动画,指的是一次触发,多个组件依次执行动画。
如我们想实现页面上的一个左箭头icon在0.5s内逐渐消失,然后在0.5s内逐渐出来一个右箭头icon。
可以使用ScaleTransition来实现上述交错动画。创建两个ScaleTransition,第一个ScaleTransition的child是一个左箭头icon,第二个ScaleTransition的child是一个右箭头icon,两个ScaleTransition共用一个AnimationController实例,假设为controller。左箭头的scale属性设为controller.drive(Tween(begin: 2.0, end: 0.0).chain(CurveTween(curve: const Interval(0, 0.5)))),即不再是孤零零的controller,而是调用controller的drive()方法得到的新的Animation实例。drive()方法需要传一个Animatable实例,Animatable是个抽象类,我们用其子类Tween。构造Tween实例时,指定begin属性值为2.0,表示左箭头一开始的size是icon的size的2倍,指定end值为0.0,表示左箭头最后缩没了。若要指定动画的执行、结束时间,需要调用Tween实例的chain()方法,得到一个新的Animatable实例。chain()方法要传一个Animatable<double>实例。我们用其子类CurveTween。构造CurveTween实例时必须指定curve属性,值是个Curve实例。Curve是个抽象类,我们用其子类Interval。构造Interval实例时,第一个参数指定动画开始执行的时间,第二个参数指定动画执行结束的时间。这两个参数都是小数,真正时间还要乘以Duration指定的时间。即假如Duration指定为10s,第一个参数是0.1,第二个参数是0.2,则其实表示的是动画从第1s开始执行,到第2s执行结束。总结起来,左箭头的scale属性表示左箭头一开始放到icon 指定size的2倍,从触发后立刻开始缩小,到0.5*Duration缩小到消失。同理把右箭头的scale属性设为controller.drive(Tween(begin: 0.0, end: 2.0).chain(CurveTween(curve: const Interval(0.5, 1)))),表示一开始不显示,从触发后0.5*Duration开始放大,到1*Duration放大到icon指定size的2倍。
通过上面例子不难看出,其实交错动画就是利用多个组件共用一个AnimationController,通过合理地给每个组件分配时间区间,让其在一定的时间区间内执行特定的动画,从而实现一连串动画。