Flutter开发——动画【总结篇】

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    1.在Flutter中动画分为两类基于tween或基于物理的。

    • 补间动画(Tween):在补间动画中定义了开始点和结束点、时间线以及定义转换时间和速度的曲线。然后由框架计算如何从开始点过渡到结束点
    • 基于物理的动画在基于物理的动画中运动被模拟为与真实世界的行为相似。

    2.Flutter中动画常用的API

    • Animation:是Flutter动画库中的一个核心类它生成指导动画的值
    • AnimationController:Animation的一个子类用来管理Animation;
    • Tween :在正在执行动画的对象所使用的数据范围之间生成值。例如Tween可生成从红到蓝之间的色值
    • AnimatedBuilder:是拆分动画的一个工具类可以将动画和Widget进行分离而AnimatedWidget理解为Animation的帮助类
    • AnimatedBuilder与AnimatedWidget的最大区别在于对动画拆分上AnimatedBuilder的模式可以将动画逻辑与widget展示进行拆分而AnimatedWidget是融合在一起的。
    (1)Animation

    在Flutter中Animation对象本身和UI渲染没有关系它是一个抽象类拥有当前值和状态。并且有一个泛型常用的是Animation<double>

    Flutter中Animation对象是一个在一段时间内依次生成一个区间之间值的类输出的值可以是线性的、曲线的或者一个任意函数。根据Animation对象的控制方式动画可以反向运行甚至可以在中间切换方向。

    • Animation还可以生成其他类型的值如Animation<Color>Animation<Size>等;
    • Animation对象有状态。可以通过其value属性获取动画的当前值
    • Animation对象本身和UI渲染没有任何关系
    (2)AnimationController

    AnimationController是一个特殊的Animation对象在屏幕刷新的每一帧就会生成一个新的值。默认情况下AnimationController在给定的时间段会线性的生成0.0到1.0的数字。例如

    final AnimationController controller = new AnimationController(duration:const Duration(milliseconds:2000),vsync:this);
    

    AnimationController派生自Animation<double>,因此可以再需要Animation对象的任何地方使用。但是AnimationController常用方法

    • forward():启动动画
    • reverse():倒放动画
    • reset():重置动画将其设置到动画的开始位置
    • stop():停止动画
      创建AnimationController时需要传一个vsync参数存在vsync时会防止屏幕外动画消耗不必要的资源可以将stateful对象作为vsync的值。
    (3)Tween

    默认情况下AnimationController对象的范围从0.0到1.0.如果需要不同范围可以设置
    final Tween tween = Tween<double>(begin: 0.0, end: 100.0);
    Tween继承了Animatable<T>。Animatable与Animation相似不是必须输出double值。例如ColorTween可以指定两种颜色之间的过渡。
    final Tween colorTween = ColorTween(begin: Colors.red, end: Colors.blue);
    Tween对象不存储任何状态。它提供了evaluate(Animation<double> animation)方法将映射函数应用于动画当前值。Animation对象的当前值可以通过value()获取。evaluate方法还执行了一些其他处理例如分别确保在动画值为0.0和1.0时返回开始和结束状态。
    Tween.animate
    要使用Tween对象可调用它的animate()方法传入一个控制器。例如

       final AnimationController controller = AnimationController(
            vsync: this, duration: const Duration(milliseconds: 500));
        Animation<int> tween = IntTween(begin: 0, end: 255).animate(controller);
    

    animate()返回一个Animation.
    结合CurvedAnimation使用

    final AnimationController controller = AnimationController(
            vsync: this, duration: const Duration(milliseconds: 500));
        final Animation<double> curve =
            CurvedAnimation(parent: controller, curve: Curves.easeOut);
        Animation<int> tween = IntTween(begin: 0, end: 255).animate(curve);
    

    3.动画添加监听器

    如果需要知道动画执行的进度和状态可以通过Animation的addListeneraddStatusListener方法给动画添加监听器

    • addListener动画的值发生变化时会被调用
    • addStatusListener动画的状态发生变化时会被调用

    4.实现一个从小到大的动画

    class LogoAnimation extends StatefulWidget {
      const LogoAnimation({Key? key}) : super(key: key);
    
      
      State<LogoAnimation> createState() => _LogoAnimationState();
    }
    
    class _LogoAnimationState extends State<LogoAnimation>
        with SingleTickerProviderStateMixin {
      Animation<double>? animation;
      AnimationController? controller;
    
      
      void initState() {
        super.initState();
        controller =
            AnimationController(vsync: this, duration: const Duration(seconds: 2));
        animation = Tween(begin: 0.0, end: 200.0).animate(controller!)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller!.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller!.forward();
            }
          })
          ..addListener(() {
            setState(() {});
          });
        controller!.forward();
      }
    
      
      void dispose() {
        controller?.dispose();
        super.dispose();
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('动画'),
          ),
          body: Center(
            child: Container(
              height: animation?.value,
              width: animation?.value,
              child: const FlutterLogo(),
            ),
          ),
        );
      }
    }
    

    5.用AnimatedWidget与AnimatedBuilder

    AnimatedWidget
    可以将AnimatedWidget理解为Animation的助手使用它可以简化对动画的使用在不使用AnimatedWidget的情况下需要手动调用动画的addListener()并在回调中添加setState才能看到动画的效果AnimatedWidget简化了这一操作。
    AnimatedBuilder
    AnimatedBuilder是用于构建动画的通用widget,AnimatedBuilder对于希望将动画作为更大构建函数的一部分包含在内的更复杂的widget时非常适用。其实AnimatedBuilder是拆分动画的一个工具类适用它可以将动画和widget进行解耦分离。

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6