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

简介: 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);
  @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),
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

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

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


目录
相关文章
|
10天前
|
容器
Flutter &&鸿蒙next中的 Stack 和 Positioned 用法详解
在 Flutter 中,Stack 和 Positioned 是创建层叠布局和灵活定位元素的常用组件。Stack 可以将多个子组件叠加在一起,允许子组件相互重叠;Positioned 用于在 Stack 内部精确控制子组件的位置。本文详细介绍了它们的基本用法、属性和应用场景,包括动画、弹出层和悬浮按钮等。
63 1
|
12天前
|
Dart 安全 编译器
Flutter结合鸿蒙next 中数据类型转换的高级用法:dynamic 类型与其他类型的转换解析
在 Flutter 开发中,`dynamic` 类型提供了灵活性,但也带来了类型安全性问题。本文深入探讨 `dynamic` 类型及其与其他类型的转换,介绍如何使用 `as` 关键字、`is` 操作符和 `whereType&lt;T&gt;()` 方法进行类型转换,并提供最佳实践,包括避免过度使用 `dynamic`、使用 Null Safety 和异常处理,帮助开发者提高代码的可读性和可维护性。
65 1
|
18天前
|
搜索推荐
Flutter 中的 AnimationController 类
【10月更文挑战第18天】深入了解了 Flutter 中的 `AnimationController`类。它是构建精彩动画效果的重要基石,掌握它的使用方法对于开发具有吸引力的 Flutter 应用至关重要。
|
3月前
|
Dart
Flutter笔记:手动配置VSCode中Dart代码自动格式化
Flutter笔记:手动配置VSCode中Dart代码自动格式化
430 5
|
3月前
|
数据安全/隐私保护 Android开发 开发者
Flutter笔记:Widgets Easier组件库-使用隐私守卫
Flutter笔记:Widgets Easier组件库-使用隐私守卫
50 2
|
3月前
|
UED 开发者
Flutter笔记:Widgets Easier组件库(13)- 使用底部弹窗
Flutter笔记:Widgets Easier组件库(13)- 使用底部弹窗
59 2
|
3月前
|
数据采集 API 调度
Flutter笔记:关于SchedulerBinding
Flutter笔记:关于SchedulerBinding
83 1
|
3月前
|
开发者
Flutter笔记:Widgets Easier组件库(11)- 使用提示吐丝(Tip Toasts)
Flutter笔记:Widgets Easier组件库(11)- 使用提示吐丝(Tip Toasts)
45 1
|
3月前
|
开发者
Flutter笔记:Widgets Easier组件库 - 使用标签(Tag)
Flutter笔记:Widgets Easier组件库 - 使用标签(Tag)
110 0
|
1月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin