• Flutter笔记:AnimationMean、AnimationMax 和 AnimationMin 三个类的用法


    Flutter笔记
    AnimationMean、AnimationMax 和 AnimationMin
    三个类的用法

    作者李俊才 (jcLee95)https://blog.csdn.net/qq_28550263
    邮箱 :291148484@163.com
    本文地址https://blog.csdn.net/qq_28550263/article/details/133417590



    1. 概述

    这三个类都用于创建复合动画,可以同时跟踪多个子动画的状态和值。它们的功能包括:

    1. AnimationMean(计算平均值):用于计算两个或多个动画的平均值。这对于创建多个动画的平均效果非常有用,例如,当您需要计算多个属性的平均值时。

    2. AnimationMax(计算最大值):用于计算两个或多个动画的最大值。这对于创建多个动画的最大效果非常有用,例如,当您需要确定多个属性的最大值时。

    3. AnimationMin(计算最小值):用于计算两个或多个动画的最小值。这对于创建多个动画的最小效果非常有用,例如,当您需要确定多个属性的最小值时。

    这些复合动画可以帮助您在应用中创建各种复杂的动画效果,例如混合动画、动态颜色变化等。通过使用 AnimationMeanAnimationMaxAnimationMin,可以轻松地管理和组合多个动画,以创建更复杂和有趣的用户界面动画效果。这些复合动画可以帮助您实现更多创意和交互性。

    2.AnimationMean(计算平均值)

    源码

    /// 一个跟踪两个其他动画平均值的双精度动画。
    ///
    /// 如果“right”动画正在移动,则此动画的[status]为“right”动画的状态,否则为“left”动画的状态。
    ///
    /// 此动画的[value]是表示“left”和“right”动画值的平均值的[double]。
    class AnimationMean extends CompoundAnimation<double> {
      /// 创建一个跟踪两个其他动画平均值的动画。
      AnimationMean({
        required Animation<double> left,
        required Animation<double> right,
      }) : super(first: left, next: right);
    
      
      double get value => (first.value + next.value) / 2.0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    AnimationMean 用于计算多个动画的平均值,其中:

    • value 属性表示这些动画的平均值。
    • status 属性表示复合动画的状态。

    用法

    Animation<double> animation1 = ...; // 第一个动画
    Animation<double> animation2 = ...; // 第二个动画
    
    // 创建 AnimationMean 来计算平均值
    Animation<double> meanAnimation = AnimationMean(left: animation1, right: animation2);
    
    // 在UI中使用 meanAnimation
    AnimatedBuilder(
      animation: meanAnimation,
      builder: (context, child) {
        return Text(
          'Mean Value: ${meanAnimation.value.toStringAsFixed(2)}',
          style: TextStyle(fontSize: 20),
        );
      },
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    当要根据多个动画的平均值创建动画效果时,AnimationMean 很有用。例如,希望 平滑地 过渡多个属性的变化时,可以使用平均值来创建更柔和的动画效果。

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: 'AnimationMean 示例',
          home: AnimationMeanDemo(),
        );
      }
    }
    
    class AnimationMeanDemo extends StatefulWidget {
      const AnimationMeanDemo({super.key});
    
      
      State<AnimationMeanDemo> createState() => _AnimationMeanDemoState();
    }
    
    class _AnimationMeanDemoState extends State<AnimationMeanDemo>
        with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _animationA;
      late Animation<double> _animationB;
    
      
      void initState() {
        super.initState();
    
        // 创建 AnimationController
        _controller = AnimationController(
          duration: const Duration(seconds: 2),
          vsync: this,
        );
    
        // 创建两个 Animation 对象来控制属性 A 和属性 B
        _animationA = Tween<double>(begin: 0, end: 100).animate(_controller);
        _animationB = Tween<double>(begin: 100, end: 200).animate(_controller);
    
        // 启动动画
        _controller.forward();
      }
    
      
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('AnimationMean 示例'),
          ),
          body: Center(
            child: AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                // 使用 AnimationMean 来创建平均值动画效果
                double meanValue = AnimationMean(
                  left: _animationA,
                  right: _animationB,
                ).value;
    
                return Container(
                  width: meanValue,
                  height: meanValue,
                  color: Colors.blue,
                  child: const Center(
                    child: Text(
                      '平均值动画示例',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    在这里插入图片描述

    3. AnimationMax(计算最大值)

    源码

    /// 跟踪两个其他动画最大值的动画。
    ///
    /// 此动画的[value]是[first]和[next]的值的最大值。
    class AnimationMax<T extends num> extends CompoundAnimation<T> {
      /// 创建一个[AnimationMax]。
      ///
      /// 两个参数都不能为空。其中一个可以是[AnimationMax]本身,以组合多个动画。
      AnimationMax(Animation<T> first, Animation<T> next) : super(first: first, next: next);
    
      
      T get value => math.max(first.value, next.value);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    AnimationMax 用于计算多个动画的最大值,其中:

    • value 属性表示这些动画的最大值。
    • status 属性表示复合动画的状态。

    用法

    Animation<double> animation1 = ...; // 第一个动画
    Animation<double> animation2 = ...; // 第二个动画
    
    // 创建 AnimationMax 来计算最大值
    Animation<double> maxAnimation = AnimationMax(animation1, animation2);
    
    // 在UI中使用 maxAnimation
    AnimatedBuilder(
      animation: maxAnimation,
      builder: (context, child) {
        return Text(
          'Max Value: ${maxAnimation.value.toStringAsFixed(2)}',
          style: TextStyle(fontSize: 20),
        );
      },
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    当要确定多个动画中的最大值时,AnimationMax 是一个有用的工具。例如,当您希望元素在多个属性的影响下保持在屏幕上的最大范围内时,可以使用最大值来创建动画效果。一个完整的例子如:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'AnimationMax 示例',
          home: AnimationMaxDemo(),
        );
      }
    }
    
    class AnimationMaxDemo extends StatefulWidget {
      
      _AnimationMaxDemoState createState() => _AnimationMaxDemoState();
    }
    
    class _AnimationMaxDemoState extends State<AnimationMaxDemo>
        with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _animationWidth;
      late Animation<double> _animationHeight;
    
      
      void initState() {
        super.initState();
    
        // 创建 AnimationController
        _controller = AnimationController(
          duration: const Duration(seconds: 2),
          vsync: this,
        );
    
        // 创建两个 Animation 对象来控制宽度和高度
        _animationWidth = Tween<double>(begin: 50, end: 200).animate(_controller);
        _animationHeight = Tween<double>(begin: 50, end: 200).animate(_controller);
    
        // 启动动画
        _controller.forward();
      }
    
      
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('AnimationMax 示例'),
          ),
          body: Center(
            child: AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                // 使用 AnimationMax 来确保元素保持在屏幕上的最大范围内
                double maxWidth = 300; // 屏幕的最大宽度
                double maxHeight = 300; // 屏幕的最大高度
    
                // 使用 AnimationMax 计算宽度和高度的最大值,以确保元素不超出屏幕
                double width =
                    AnimationMax<double>(_animationWidth, _animationHeight).value;
                double height =
                    AnimationMax<double>(_animationHeight, _animationWidth).value;
    
                return Container(
                  width: width > maxWidth ? maxWidth : width,
                  height: height > maxHeight ? maxHeight : height,
                  color: Colors.blue,
                  child: const Center(
                    child: Text(
                      '最大值动画示例',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    在这里插入图片描述

    4. AnimationMin(计算最小值)

    源码

    /// 一个跟踪两个其他动画最小值的动画。
    ///
    /// 该动画的[value]是[first]和[next]的值的最小值。
    class AnimationMin<T extends num> extends CompoundAnimation<T> {
      /// 创建一个[AnimationMin]。
      ///
      /// 两个参数都不能为空。要合并多个动画,其中任一个都可以是[AnimationMin]本身。
      AnimationMin(Animation<T> first, Animation<T> next) : super(first: first, next: next);
    
      
      T get value => math.min(first.value, next.value);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    用法

    Animation<double> animation1 = ...; // 第一个动画
    Animation<double> animation2 = ...; // 第二个动画
    
    // 创建 AnimationMin 来计算最小值
    Animation<double> minAnimation = AnimationMin(animation1, animation2);
    
    // 在UI中使用 minAnimation
    AnimatedBuilder(
      animation: minAnimation,
      builder: (context, child) {
        return Text(
          'Min Value: ${minAnimation.value.toStringAsFixed(2)}',
          style: TextStyle(fontSize: 20),
        );
      },
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    AnimationMin 用于计算多个动画的最小值。其中:

    • value 属性表示这些动画的最小值。
    • status 属性表示复合动画的状态。

    需要确定多个动画中的最小值时,AnimationMin 是一个有用的工具。 例如,希望元素在多个属性的影响下保持在屏幕上的最小范围内时,可以使用最小值来创建动画效果。例如:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: 'AnimationMin 示例',
          home: AnimationMinDemo(),
        );
      }
    }
    
    class AnimationMinDemo extends StatefulWidget {
      const AnimationMinDemo({super.key});
    
      
      State<AnimationMinDemo> createState() => _AnimationMinDemoState();
    }
    
    class _AnimationMinDemoState extends State<AnimationMinDemo>
        with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _animationWidth;
      late Animation<double> _animationHeight;
    
      
      void initState() {
        super.initState();
    
        // 创建 AnimationController
        _controller = AnimationController(
          duration: const Duration(seconds: 2),
          vsync: this,
        );
    
        // 创建两个 Animation 对象来控制元素的宽度和高度
        _animationWidth = Tween<double>(begin: 50, end: 200).animate(_controller);
        _animationHeight = Tween<double>(begin: 50, end: 200).animate(_controller);
    
        // 启动动画
        _controller.forward();
      }
    
      
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('AnimationMin 示例'),
          ),
          body: Center(
            child: AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                // 使用 AnimationMin 来确保元素的宽度和高度不会超出屏幕边界的最小范围
                double minWidth = 50; // 最小宽度
                double minHeight = 50; // 最小高度
    
                // 使用 AnimationMin 计算宽度和高度的最小值,以确保元素不会超出屏幕边界
                double width =
                    AnimationMin<double>(_animationWidth, _animationHeight).value;
                double height =
                    AnimationMin<double>(_animationHeight, _animationWidth).value;
    
                return Container(
                  width: width < minWidth ? minWidth : width,
                  height: height < minHeight ? minHeight : height,
                  color: Colors.blue,
                  child: const Center(
                    child: Text(
                      '最小值动画示例',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
  • 相关阅读:
    华为ENSP网络设备配置实战2(较为复杂的ospf)
    C++ LibCurl实现Web隐藏目录扫描
    绝地求生【商城更新】WIA联名上架//专属商店下架
    如何将Python程序打包并保护源代码
    qt环境配置
    解决mybatis case when 报错的问题
    python排序算法
    基础 | 并发编程 - [锁]
    Laravel 事件(event)+ 队列(queue)基础
    FPGA 之 设计实现过程
  • 原文地址:https://blog.csdn.net/qq_28550263/article/details/133417590