Flutter Animation(1)动画的简单使用

在动画过程中,需要两个部分:

  1. 第一个就是动画控制类,它不需要知道在屏幕上显示什么。
  2. 第二个就是实际上的UI元素

1. 动画控制类

动画控制类有两部分:

  1. Animation

    Animation类对象是一个抽象类,支持泛型,我们常用的是Animation<double>,当然这里不仅仅是double,可以是任意一个对象。Animation对象本身和UI渲染没有任何关系,而是用于生产动画过程中的值,用这个值来控制动画,也能获取当前动画的状态(正在播放中,还是结束等),也能获取动画播放过程中的当前值。而且Animation类有很多不同的子类,用于实现不同的动画效果,我们下篇在将。

  2. AnimationController

    AnimationController一方面是用来管理Animation,比如动画的开关,另一方面,AnimationControllerAnimation还有另外一种关系,就是AnimationController是输入,是X,它的范围是从0.0到1.0的数字,经过Animation里定义的f(),映射到对应的Y值,

所以AnimationAnimationController是在动画中比不可少的元素,而且这两个一定是搭配使用的。看代码:

//定义的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元素上呢?

总共有三种方法:

  1. 原始方法

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();
      }
    }
复制代码
  1. 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),
      ),
    ));
  }
}
复制代码
  1. AnimatedBuilder

    前面的AnimatedWidget,我要是每实现一个动画就单独抽出来一个class文件来写Widget,太复杂了,所以有了AnimatedBuilderAnimatedBuilder可以更方便的为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),
                ),
              );
            },
          ),
        );
      }
    }
复制代码

猜你喜欢

转载自juejin.im/post/5c460919e51d4507fb1d7b94