内容简介:在动画过程中,需要两个部分:动画控制类有两部分:所以
在动画过程中,需要两个部分:
- 第一个就是动画控制类,它不需要知道在屏幕上显示什么。
- 第二个就是实际上的UI元素
1. 动画控制类
动画控制类有两部分:
-
Animation
Animation
类对象是一个抽象类,支持泛型,我们常用的是Animation<double>
,当然这里不仅仅是double,可以是任意一个对象。Animation对象本身和UI渲染没有任何关系,而是用于生产动画过程中的值,用这个值来控制动画,也能获取当前动画的状态(正在播放中,还是结束等),也能获取动画播放过程中的当前值。而且Animation
类有很多不同的子类,用于实现不同的动画效果,我们下篇在将。 -
AnimationController
AnimationController
一方面是用来管理Animation
,比如动画的开关,另一方面,AnimationController
和Animation
还有另外一种关系,就是AnimationController
是输入,是X,它的范围是从0.0到1.0的数字,经过Animation
里定义的f(),映射到对应的Y值,
所以 Animation
和 AnimationController
是在动画中比不可少的元素,而且这两个一定是搭配使用的。看代码:
//定义的AnimationController,动画时长2000ms AnimationController controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 2000)); //Tween是Animation的子类,其实是定义了一种f(),Y的值是从50到200 //.animate(controller)是一定要调用的 Animation<double> animation = Tween(begin: 50.0, end: 200.0).animate(controller); //动画控制,开始播放 controller.forward(); 复制代码
2 使用动画
讲完了动画控制类,这个动画控制类怎么运用到UI元素上呢?
总共有三种方法:
- 原始方法
将 Animation
的值直接用到widget的属相上,用这种方法时,一定要记得 Animation
里要添加动画的监听 addListener
方法, addListener
方法里要调用 setState(() {})
。
因为虽然 Animation
的值变了,但如果不调用 setState(() {})
的话,widget就不会重新绘制。
class AnimApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _AnimAppState(); } } class _AnimAppState extends State<AnimApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation<double> animation; @override void initState() { super.initState(); controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 2000)); animation = Tween(begin: 50.0, end: 200.0).animate(controller) ..addListener(() { setState(() {}); }); controller.forward(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Container( width: animation.value, height: animation.value, decoration: BoxDecoration(color: Colors.redAccent), ), )); } @override void dispose() { controller.dispose(); super.dispose(); } } 复制代码
-
AnimatedWidget
AnimatedWidget
是Flutter将动画封装成了Widget,更方便使用,而且不需要调用setState()
,AnimatedWidget
也有很多子类,这次先不介绍,先看它的普通使用,AnimatedWidget
需要一个Animation
的参数:
class AnimApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _AnimAppState(); } } class _AnimAppState extends State<AnimApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation<double> animation; @override void initState() { super.initState(); controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 2000)); animation = Tween(begin: 50.0, end: 200.0).animate(controller); controller.repeat(); } @override Widget build(BuildContext context) { return Scaffold( body: AnimApp2(animation: animation,), ); } } class AnimApp2 extends AnimatedWidget { AnimApp2({Key key, Animation<double> animation}) : super(key: key, listenable: animation); @override Widget build(BuildContext context) { final Animation<double> animation = listenable; return Scaffold( body: Center( child: Container( width: animation.value, height: animation.value, decoration: BoxDecoration(color: Colors.redAccent), ), )); } } 复制代码
-
AnimatedBuilder
前面的
AnimatedWidget
,我要是每实现一个动画就单独抽出来一个class文件来写Widget,太复杂了,所以有了AnimatedBuilder
,AnimatedBuilder
可以更方便的为Widget添加动画,看代码:
class AnimApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _AnimAppState(); } } class _AnimAppState extends State<AnimApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation<double> animation; @override void initState() { super.initState(); controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 2000)); animation = Tween(begin: 50.0, end: 200.0).animate(controller); controller.repeat(); } @override Widget build(BuildContext context) { return Scaffold( body: AnimatedBuilder( animation: animation, builder: (context, child) { return Center( child: Container( width: animation.value, height: animation.value, decoration: BoxDecoration(color: Colors.redAccent), ), ); }, ), ); } } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。