美文网首页fullter
Flutter 动画基础

Flutter 动画基础

作者: 望穿秋水小作坊 | 来源:发表于2020-07-15 11:21 被阅读0次
    Flutter 动画基础

    一:使用 AnimationController 实现缩放动画

    
    class ScaleAnimationRoute extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _ScaleAnimationRouteState();
      }
    }
    
    // 需要继承 TickerProvider , 如果有多个 AnimationController,则应该使用 TickerProviderStateMixin
    class _ScaleAnimationRouteState extends State<ScaleAnimationRoute>
        with SingleTickerProviderStateMixin {
      Animation<double> animation;
    
      @override
      void initState() {
        super.initState();
    
        // 这个家伙独立就可以完成整个动画
        controller = new AnimationController(
            vsync: this,
            duration: const Duration(seconds: 1),
            lowerBound: 10.0,
            upperBound: 400.0)
          ..addListener(() {
            setState(() => {});
          });
    
        // 启动动画(正向执行)
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return Image.asset(
          "images/avatar.jpg",
          width: controller.value,
          height: controller.value,
        );
      }
    
      @override
      void dispose() {
        // 需要进行释放,以免内存泄露
        controller.dispose();
        super.dispose();
      }
    }
    
    

    二:使用 AnimationController + CurvedAnimation + Tween 实现缩放动画

    // 需要继承 TickerProvider , 如果有多个 AnimationController,则应该使用 TickerProviderStateMixin
    class _ScaleAnimationRouteState extends State<ScaleAnimationRoute>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      CurvedAnimation curvedAnimation;
      Animation<double> animation;
    
      @override
      void initState() {
        super.initState();
    
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
    
        curvedAnimation =
            CurvedAnimation(parent: controller, curve: Curves.decelerate);
    
        // 图片宽高从 0 变到 300
        animation = new Tween(begin: 0.0, end: 300.0).animate(curvedAnimation)
          ..addListener(() {
            setState(() => {});
          });
    
        // 启动动画(正向执行)
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return Image.asset(
          "images/avatar.jpg",
          width: animation.value,
          height: animation.value,
        );
      }
    
      @override
      void dispose() {
        // 需要进行释放,以免内存泄露
        controller.dispose();
        super.dispose();
      }
    }
    

    三:使用 AnimatedBuilder 重构

    class ScaleAnimationRoute extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _ScaleAnimationRouteState();
      }
    }
    
    // 需要继承 TickerProvider , 如果有多个 AnimationController,则应该使用 TickerProviderStateMixin
    class _ScaleAnimationRouteState extends State<ScaleAnimationRoute>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      CurvedAnimation curvedAnimation;
      Animation<double> animation;
    
      @override
      void initState() {
        super.initState();
    
        controller = new AnimationController(
            duration: const Duration(seconds: 3), vsync: this);
    
        curvedAnimation =
            CurvedAnimation(parent: controller, curve: Curves.decelerate);
    
        // 图片宽高从 0 变到 300
        animation = new Tween(begin: 0.0, end: 300.0).animate(curvedAnimation);
    
        // 启动动画(正向执行)
        controller.forward();
      }
    
      @override
      Widget build(BuildContext context) {
        return GrowTransition(
          child: Image.asset("images/333.jpg"),
          animation: animation,
        );
      }
    
      @override
      void dispose() {
        // 需要进行释放,以免内存泄露
        controller.dispose();
        super.dispose();
      }
    }
    
    class GrowTransition extends StatelessWidget {
      GrowTransition({this.child, this.animation});
      final Widget child;
      final Animation<double> animation;
    
      @override
      Widget build(BuildContext context) {
        return new Center(
          child: new AnimatedBuilder(animation: animation, child: child ,builder: (BuildContext context, Widget child){
            return new Container(
              height: animation.value,
              width: animation.value,
              child: child,
            );
          }),
        );
      }
    }
    

    优点

    1. 不用显式的去添加帧监听器,然后再调用 setState() 了,这个好处和 AnimatedWidget 是一样的。
    2. 动画构建的范围缩小了,如果没有 Builder,setState()将会在父组件上下文中调用,这将会导致父组件的 build 方法重新调用;而有了 builder 之后,只会导致动画 widget 自身的 build 重新调用,避免不必要的 rebuild。
    3. 通过 AnimatedBuilder 可以封装常见的过渡效果来复用动画。

    四:让动画永动起来。

    initState() {
        super.initState();
        controller = new AnimationController(
            duration: const Duration(seconds: 1), vsync: this);
        //图片宽高从0变到300
        animation = new Tween(begin: 0.0, end: 300.0).animate(controller);
        animation.addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            //动画停在结束状态时反向执行动画
            controller.reverse();
          } else if (status == AnimationStatus.dismissed) {
            //动画停在初始状态时执行动画(正向)
            controller.forward();
          }
        });
    
        //启动动画(正向)
        controller.forward();
      }
    

    循环动画,这种动画效果,我们只需要监听动画状态改变即可。

    相关文章

      网友评论

        本文标题:Flutter 动画基础

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