美文网首页Flutter
Flutter(三十六)Animation动画

Flutter(三十六)Animation动画

作者: 天色将变 | 来源:发表于2019-07-20 15:47 被阅读0次
    一.图片放大示例

    要点:

    • AnimationController,用于设定动画的执行时间,以及动画的开启、反转等动作。
      controller = new AnimationController(duration: const Duration(seconds: 4), vsync: this);
    • Animation,用于设定动画取值范围,并可增加动画监听,addListener是帧监听,每一帧都会回调。
      animation = new Tween(begin: 100.0, end: 300.0).animate(controller)
      ..addListener(() {
      // 通过setState实现重绘
      setState(() => {});
      });
    • controller.forward() // 启动动画
    • controller.dispose() // 释放动画资源
    image.png
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      initState() {
        super.initState();
        // 设定动画执行时间
        controller = new AnimationController(
            duration: const Duration(seconds: 4), vsync: this);
        //图片宽高从100变到300
        animation = new Tween(begin: 100.0, end: 300.0).animate(controller)
          ..addListener(() {
            // 通过setState实现重绘
            setState(() => {});
          });
        //启动动画
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: Image.asset("images/avatar.jpg",
              width: animation.value, height: animation.value),
        );
      }
    
      dispose() {
        //释放动画资源
        controller.dispose();
        super.dispose();
      }
    }
    
    
    二.取值变化曲线

    变化的取值,从begin到end,默认是线性变化的。变化过程可以设定曲线函数,如:

    • animation=CurvedAnimation(parent: controller, curve: Curves.bounceIn);

    Curves 变化曲线,有很多种:

    • linear 线性
    • bounceIn 弹性
    • ease 开始快后来慢
    • easeIn 开始慢后来快
    • 。。。。。。
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      initState() {
        super.initState();
        // 设定动画执行时间
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
        // 值变化曲线
        animation=CurvedAnimation(parent: controller, curve: Curves.bounceIn);
        //图片宽高从100变到300
        animation = new Tween(begin: 100.0, end: 400.0).animate(animation)
          ..addListener(() {
            // 通过setState实现重绘
            setState(() => {});
          });
        //启动动画
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: Image.asset("images/avatar.jpg",
              width: animation.value, height: animation.value),
        );
      }
    
      dispose() {
        //释放动画资源
        controller.dispose();
        super.dispose();
      }
    }
    
    三.AnimatedWidget

    上面使用addListener和setState实现重绘,AnimatedWidget则简化了这个操作。继承AnimatedWidget后,可以直接使用animation的值。

    class AnimatedImage extends AnimatedWidget {
      AnimatedImage({Key key, Animation<double> animation})
          : super(key: key, listenable: animation);
    
      Widget build(BuildContext context) {
        final Animation<double> animation = listenable;
        return new Center(
          child: Image.asset("images/avatar.jpg",
              width: animation.value,
              height: animation.value
          ),
        );
      }
    }
    
    
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      initState() {
        super.initState();
        // 设定动画执行时间
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
        // 值变化曲线
        animation=CurvedAnimation(parent: controller, curve: Curves.bounceIn);
        //图片宽高从100变到300
        animation = new Tween(begin: 100.0, end: 400.0).animate(animation);
        //启动动画
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedImage(animation: animation,);
      }
    
      dispose() {
        //释放动画资源
        controller.dispose();
        super.dispose();
      }
    }
    
    四. AnimatedBuilder

    构造方法:

    const AnimatedBuilder({
        Key key,
        @required Listenable animation,
        @required this.builder,
        this.child,
      }) 
    
    • animation 定义的动画
    • child 作用的目标,也就是要给哪个widget添加动画
    • build 封装了绘制过程
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      initState() {
        super.initState();
        // 设定动画执行时间
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
        // 值变化曲线
        animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);
        //图片宽高从100变到300
        animation = new Tween(begin: 100.0, end: 400.0).animate(animation);
        //启动动画
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          animation: animation,
          child: Image.asset("images/avatar.jpg"),
          builder: (BuildContext context, Widget child) {
            return new Center(
              child: Container(
                height: animation.value,
                width: animation.value,
                child: child,
              ),
            );
          },
        );
      }
    
      dispose() {
        //释放动画资源
        controller.dispose();
        super.dispose();
      }
    }
    
    五.封装动画

    将动画与目标分离开,制定动画过程,传入目标child widget。

    class GrowTransition extends StatelessWidget {
      GrowTransition({this.child, this.animation});// 传入目标和动画设定
    
      final Widget child;
      final Animation<double> animation;
    
    // 对目标child设置动画执行过程
      Widget build(BuildContext context) {
        return new Center(
          child: new AnimatedBuilder(
              animation: animation,
              builder: (BuildContext context, Widget child) {
                return new Container(
                    height: animation.value, 
                    width: animation.value, 
                    child: child
                );
              },
              child: child
          ),
        );
      }
    }
    
    
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      initState() {
        super.initState();
        // 设定动画执行时间
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
        // 值变化曲线
        animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);
        //图片宽高从100变到300
        animation = new Tween(begin: 100.0, end: 400.0).animate(animation);
        //启动动画
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return GrowTransition(
          animation: animation,
          child: Image.asset("images/avatar.jpg"),
        );
      }
    
      dispose() {
        //释放动画资源
        controller.dispose();
        super.dispose();
      }
    }
    
    六.状态监听器
    • addListener 是每一帧的监听回调
    • addStatusListener 监听的是动画过程的状态,包括:
      • dismissed 动画停止
      • forward 动画开始正向执行
      • reverse 动画开始反向执行
      • completed 动画执行完毕
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      initState() {
        super.initState();
        // 设定动画执行时间
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
        // 值变化曲线
        animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);
        //图片宽高从100变到300
        animation = new Tween(begin: 100.0, end: 400.0).animate(animation);
        // 添加状态监听
        animation.addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            //动画执行结束时反向执行动画
            controller.reverse();
          } else if (status == AnimationStatus.dismissed) {
            //动画恢复到初始状态时执行动画(正向)
            controller.forward();
          }
        });
        //启动动画
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return GrowTransition(
          animation: animation,
          child: Image.asset("images/avatar.jpg"),
        );
      }
    
      dispose() {
        //释放动画资源
        controller.dispose();
        super.dispose();
      }
    }
    
    欢迎关注我的公众号:Flutter和Dart开发实践
    让我们共同学习进步,It is never too late to learn!
    image.png

    相关文章

      网友评论

        本文标题:Flutter(三十六)Animation动画

        本文链接:https://www.haomeiwen.com/subject/scculctx.html