作者李俊才 (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);

  @override
  double get value => (first.value + next.value) / 2.0;
}

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),
    );
  },
)

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

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'AnimationMean 示例',
      home: AnimationMeanDemo(),
    );
  }
}

class AnimationMeanDemo extends StatefulWidget {
  const AnimationMeanDemo({super.key});

  @override
  State<AnimationMeanDemo> createState() => _AnimationMeanDemoState();
}

class _AnimationMeanDemoState extends State<AnimationMeanDemo>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animationA;
  late Animation<double> _animationB;

  @override
  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();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  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),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

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

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);

  @override
  T get value => math.max(first.value, next.value);
}

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),
    );
  },
)

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

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AnimationMax 示例',
      home: AnimationMaxDemo(),
    );
  }
}

class AnimationMaxDemo extends StatefulWidget {
  @override
  _AnimationMaxDemoState createState() => _AnimationMaxDemoState();
}

class _AnimationMaxDemoState extends State<AnimationMaxDemo>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animationWidth;
  late Animation<double> _animationHeight;

  @override
  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();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  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),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

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

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);

  @override
  T get value => math.min(first.value, next.value);
}

用法

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),
    );
  },
)

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

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

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

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'AnimationMin 示例',
      home: AnimationMinDemo(),
    );
  }
}

class AnimationMinDemo extends StatefulWidget {
  const AnimationMinDemo({super.key});

  @override
  State<AnimationMinDemo> createState() => _AnimationMinDemoState();
}

class _AnimationMinDemoState extends State<AnimationMinDemo>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animationWidth;
  late Animation<double> _animationHeight;

  @override
  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();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  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),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

09-29 16:10