Flutter组合动画学习

ops/2024/12/22 13:29:03/

如何使用动画控制器和动画来创建一个简单的动画效果。具体来说,它通过一个 `AnimationController` 来控制两个动画,一个用于旋转,一个用于绘制。

前置知识点学习

SingleTickerProviderStateMixin

`SingleTickerProviderStateMixin` 是 Flutter 中一个常用的混入(mixin),用于提供 `Ticker` 对象的简单实现。`Ticker` 是动画时间驱动的核心组件,能够在每一帧时调用回调方法。`SingleTickerProviderStateMixin` 通常用于需要一个 `AnimationController` 的 `State` 类中。

关键点

  • `Ticker`:它是一个计时器,在每一帧调用一个回调。用于驱动动画。
  • `AnimationController`:依赖于 `Ticker` 来更新动画的状态。`AnimationController` 需要一个 `TickerProvider` 来提供 `Ticker`。
  • `SingleTickerProviderStateMixin`:提供一个 `Ticker`,适用于仅需要一个 `Ticker` 的动画场景。

代码示例

以下是一个简单的例子,展示如何在 `State` 类中使用 `SingleTickerProviderStateMixin` 来创建一个动画:

import 'package:flutter/material.dart';class MyAnimatedWidget2 extends StatefulWidget {const MyAnimatedWidget2({super.key});@override_MyAnimatedPageState createState() {return _MyAnimatedPageState();}
}class _MyAnimatedPageState extends State<MyAnimatedWidget2>with SingleTickerProviderStateMixin {late AnimationController _controller;late Animation<double> _animation;@overridevoid initState() {super.initState();// 初始化 AnimationController_controller = AnimationController(vsync: this,duration: const Duration(seconds: 2),);// 定义一个简单的补间动画(从 0 到 1)_animation = Tween<double>(begin: 0, end: 1).animate(_controller);// 启动动画_controller.forward();}@overridevoid dispose() {// 释放资源_controller.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Simple Animation"),),body: Center(child: AnimatedBuilder(animation: _animation,builder: (context, child) {return Opacity(opacity: _animation.value,child: Container(width: 200,height: 200,color: Colors.blue,),);},),),);}
}

### 解释

  • `with SingleTickerProviderStateMixin`: 这个混入使得 `_MyHomePageState` 类能够作为 `TickerProvider` 使用,提供给 `AnimationController` 使用。
  • `vsync: this`: 这里的 `vsync` 参数指定了 `TickerProvider`,通过 `SingleTickerProviderStateMixin`,`this` 就是当前的 `State`,因此可以直接使用。
  • `AnimationController`: 负责管理动画的状态和时间线。通过 `forward()`、`reverse()` 等方法来控制动画的播放。
  • `Tween` 和 `Animation`: `Tween` 定义了动画的值范围,而 `Animation` 是驱动这个值变化的实际对象。
  • `AnimatedBuilder`: 用于构建依赖于动画的 UI,每次动画状态改变时都会重新构建。

通过 `SingleTickerProviderStateMixin`,你可以轻松地在 Flutter 中实现简单的动画效果,而不必手动管理 `Ticker` 的生命周期。对于需要

总结

`SingleTickerProviderStateMixin` 是一个便捷的工具,用于实现需要单个 `Ticker` 的动画场景。

Opacity

在 Flutter 中,`Opacity` 是一个用于控制子组件透明度的控件。通过调整透明度,你可以使一个组件部分或完全透明。这在构建具有视觉层次和动态效果的用户界面时非常有用。

基本用法

`Opacity` 小部件接受一个 `opacity` 参数,该参数是一个 `double` 类型的值,范围从 0.0 到 1.0:

  • `0.0` 表示完全透明(不可见)。
  • `1.0` 表示完全不透明(可见)。

示例

import 'package:flutter/material.dart';class OpacityExample extends StatelessWidget {const OpacityExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Opacity Example'),),body: Center(child: Opacity(opacity: 0.5,child: Container(width: 100,height: 100,color: Colors.blue,),),),);}
}

关键点

1.性能考虑:`Opacity` 是一个相对简单的控件,但在某些情况下可能会影响性能,特别是当它包裹着一个复杂的子组件时。对于简单的颜色变化,使用 `Colors` 的 `withOpacity` 方法可能更高效。

2.动画效果:与 `AnimationController` 和 `AnimatedBuilder` 配合使用,可以创建平滑的透明度动画。例如,将 `Opacity` 结合 `Tween` 和 `Animation` 来实现淡入淡出效果。

3.子组件属性:`Opacity` 影响其子组件的可见性,但它不会改变子组件的布局特性。即使完全透明,子组件仍然占据布局空间。

4.替代方法:在某些情况下,`FadeTransition` 可能是更好的选择,特别是在需要动画时。`FadeTransition` 专门用于处理透明度动画,并直接与 `Animation` 对象集成。

 使用场景

  • 视觉效果:在创建具有层次的 UI 时,使用透明度来突出显示或淡化特定元素。
  • 动画:在创建淡入淡出效果时,使用 `Opacity` 结合动画控制器。
  • 动态 UI:在响应用户交互时,通过透明度变化来反馈状态变化。

通过灵活运用 `Opacity`,你可以在 Flutter 应用中创建丰富且动态的视觉效果。

RotationTransition

`RotationTransition` 是 Flutter 中的一个动画小部件,用于在一段时间内对其子组件应用旋转动画。它是构建动画的一种便捷方式,特别适合需要对组件进行旋转效果的场景。

主要属性

  • `turns`: 这是一个 `Animation` 类型的属性,定义了旋转的角度。角度是以圈(revolution)为单位的,比如 0.25 表示旋转 90 度(即四分之一圈),1.0 表示旋转 360 度(即一整圈)。
  • `child`: 需要旋转的子组件。`RotationTransition` 将对这个组件施加旋转效果。

 使用方法

`RotationTransition` 通常与 `AnimationController` 和 `Tween` 一起使用。`AnimationController` 用于控制动画的时长和播放状态,而 `Tween` 用于定义动画的起始和结束值。

示例

以下是一个简单的示例,展示如何使用 `RotationTransition` 实现一个简单的旋转动画:

import 'package:flutter/material.dart';class RotationTransitionExample extends StatefulWidget {const RotationTransitionExample({super.key});@override_RotationTransitionExampleState createState() {return _RotationTransitionExampleState();}
}class _RotationTransitionExampleState extends State<RotationTransitionExample>with SingleTickerProviderStateMixin {late AnimationController _controller;@overridevoid initState() {super.initState();_controller = AnimationController(vsync: this,duration: const Duration(seconds: 2),)..repeat();}@overridevoid dispose() {_controller.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('RotationTransition Example'),),body: Center(child: RotationTransition(turns: _controller,child: Container(width: 100.0,height: 100.0,color: Colors.blue,),),),);}
}

解释

  • `AnimationController`: 控制动画的时长和播放方式。在 `initState` 中初始化,并设置为循环播放。
  • `RotationTransition`: 使用 `AnimationController` 的值作为 `turns` 属性。这个值从 0.0 到 1.0 不断变化,实现旋转效果。
  • `child`: 被旋转的组件,在这个例子中是一个蓝色的 `Container`。

 使用场景

  • 旋转图标或按钮:可以用来制作旋转加载指示器、旋转按钮等。
  • 动态效果:在用户交互时,通过旋转来提供视觉反馈。
  • 动画过渡:在组件状态变化时,使用旋转动画增强用户体验。

通过使用 `RotationTransition`,你可以轻松地在 Flutter 应用中实现旋转动画效果,增强应用的动态交互体验。

Tween

在 Flutter 中,`Tween` 是动画框架中一个核心组件,用于定义从一个值到另一个值的插值(interpolation)。它提供了一种简单的方式来指定动画的起始值和结束值,并在动画过程中计算这些值之间的中间值。

主要功能

`Tween` 的主要功能是生成一系列的值,这些值在动画的生命周期内从起始值逐渐变化到结束值。这对于创建平滑的动画效果非常重要。

基本属性

  • `begin`: 动画的起始值。
  • `end`: 动画的结束值。

工作原理

  • `Tween` 通过一个 `Animation` 对象(通常是 `Animation`)来驱动,其 `value` 属性在 0.0 到 1.0 之间变化。
  • `Tween` 的 `lerp(double t)` 方法用于计算动画的当前值,其中 `t` 是 `Animation` 的当前进度。

常见使用场景

1.简单的数值动画: 使用 `Tween` 在两个数值之间插值。

2.颜色动画: 使用 `ColorTween` 在两种颜色之间过渡。

3.尺寸和位置动画: 使用 `SizeTween` 或 `RectTween` 在不同的尺寸或位置之间插值。

示例代码

以下是一个简单的例子,展示如何使用 `Tween` 和 `AnimationController` 创建一个从 0 到 300 的动画:

import 'package:flutter/material.dart';class TweenExample extends StatefulWidget {const TweenExample({super.key});@override_TweenExampleState createState() {return _TweenExampleState();}
}class _TweenExampleState extends State<TweenExample>with SingleTickerProviderStateMixin {late AnimationController _controller;late Animation<double> _animation;@overridevoid initState() {super.initState();_controller = AnimationController(duration: const Duration(seconds: 2),vsync: this,);// 定义一个 Tween 从 0 到 300_animation = Tween<double>(begin: 0, end: 300).animate(_controller)..addListener(() {setState(() {});});// 启动动画_controller.forward();}@overridevoid dispose() {_controller.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Tween Example'),),body: Center(child: Container(width: _animation.value,height: _animation.value,color: Colors.blue,),),);}
}

解释

  • `AnimationController`: 控制动画的时长和进度。
  • `Tween(begin: 0, end: 300)`: 定义了一个从 0 到 300 的插值。
  • `animate(_controller)`: 将 `Tween` 连接到 `AnimationController`,以便在动画进度更改时计算当前值。
  • `addListener`: 每当动画的值改变时,重新构建 UI。

Paint

在 Flutter 中,`Paint` 是一个用于配置绘图操作的类。它包含了关于如何绘制图形、文本和图像的详细信息。`Paint` 可以用来指定颜色、样式、阴影、混合模式等属性,是自定义绘制的核心工具之一。

基本属性

`Paint` 有许多属性可以配置绘图行为,以下是一些常用的属性:

  • `color`: 设置绘制内容的颜色。
  • `style`: 定义绘制的风格,可以是 `PaintingStyle.fill`(填充)或 `PaintingStyle.stroke`(描边)。
  • `strokeWidth`: 描边的宽度,仅在 `style` 为 `stroke` 时有效。
  • `blendMode`: 定义颜色如何与现有的绘制内容混合。
  • `shader`: 用于渐变或复杂的着色效果。
  • `maskFilter`: 用于模糊和其他效果。
  • `filterQuality`: 定义图片的质量(如在缩放时)。
  • `isAntiAlias`: 是否对绘制进行抗锯齿处理。
  • `strokeCap`: 描边的末端形状,可以是 `StrokeCap.round`、`StrokeCap.butt`、或 `StrokeCap.square`。
  • `strokeJoin`: 描边的连接方式,可以是 `StrokeJoin.miter`、`StrokeJoin.round`、或 `StrokeJoin.bevel`。

使用场景

`Paint` 通常与 `Canvas` 结合使用,通过 `CustomPainter` 来实现自定义绘制。`CustomPainter` 提供了两个主要方法:`paint(Canvas, Size)` 和 `shouldRepaint(CustomPainter oldDelegate)`。

代码示例

import 'package:flutter/material.dart';
class CirclePainter extends CustomPainter {@overridevoid paint(Canvas canvas, Size size) {final paint = Paint()..color = Colors.blue..style = PaintingStyle.fill; // 濉厖鏍峰紡final center = Offset(size.width / 2, size.height / 2);final radius = size.width / 4;canvas.drawCircle(center, radius, paint);}@overridebool shouldRepaint(CustomPainter oldDelegate) => false;
}
class PaintExample extends StatelessWidget {const PaintExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Paint Example'),),body: Center(child: CustomPaint(size: const Size(200, 200),painter: CirclePainter(),),),);}
}

解释

  • `CustomPainter`: 一个抽象类,用于自定义绘制。通过实现 `paint` 方法来定义绘制逻辑。
  • `Canvas`: 提供了用于绘制的基本操作,比如 `drawCircle`、`drawRect`、`drawPath` 等。
  • `Paint`: 配置绘制操作的细节,比如颜色和样式。
  • `CustomPaint`: 一个小部件,用于在 Flutter UI 中展示自定义绘制的内容。

CustomPaint

`CustomPaint` 是 Flutter 中的一个小部件,用于在屏幕上绘制自定义图形。通过结合 `CustomPainter` 类,`CustomPaint` 可以实现复杂的绘制逻辑。

主要组成部分

1.`CustomPainter`: 一个抽象类,你需要继承并实现它的 `paint` 方法来定义绘制逻辑。`CustomPainter` 是 `CustomPaint` 的核心部分。

2.`CustomPaint` 小部件: 它包含一个 `painter` 属性,该属性接收一个 `CustomPainter`

属性

  • `painter`: 一个 `CustomPainter` 对象,负责绘制主要内容。
  • `foregroundPainter`: 类似于 `painter`,但绘制在子组件的前景(在子组件上面)。
  • `child`: 可选的子组件,当需要在自定义绘制的背景或前景上叠加组件时使用。
  • `size`: 指定 `CustomPaint` 的大小。如果未设置,将会使用子组件的大小。

示例

以下是一个使用 `CustomPaint` 绘制简单图形的示例:

import 'package:flutter/material.dart';class MyPainter extends CustomPainter {@overridevoid paint(Canvas canvas, Size size) {final paint = Paint()..color = Colors.blue..style = PaintingStyle.fill;// 绘制一个圆形final circleCenter = Offset(size.width / 2, size.height / 2);final circleRadius = size.width / 4;canvas.drawCircle(circleCenter, circleRadius, paint);// 绘制一个矩形final rect = Rect.fromLTWH(50, 50, size.width - 100, size.height - 100);paint.color = Colors.red;canvas.drawRect(rect, paint);}@overridebool shouldRepaint(CustomPainter oldDelegate) => false;
}class CustomPaintExample extends StatelessWidget {const CustomPaintExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('CustomPaint Example'),),body: Center(child: CustomPaint(size: const Size(200, 200),painter: MyPainter(),),),);}
}

组合动画代码学习

import 'package:flutter/material.dart';class AnimaDemoPage extends StatefulWidget {const AnimaDemoPage({super.key});@override_AnimaDemoPageState createState() => _AnimaDemoPageState();
}class _AnimaDemoPageState extends State<AnimaDemoPage>with SingleTickerProviderStateMixin {late AnimationController controller1;Animation? animation1;late Animation animation2;@overridevoid initState() {super.initState();controller1 =AnimationController(vsync: this, duration: const Duration(seconds: 3));animation1 = Tween(begin: 0.0, end: 200.0).animate(controller1)..addListener(() {setState(() {});});animation2 = Tween(begin: 0.0, end: 1.0).animate(controller1);controller1.repeat();}@overridevoid dispose() {controller1.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("AnimaDemoPage"),),body: RotationTransition(turns: animation2 as Animation<double>,child: Center(child: Container(height: 200,width: 200,color: Colors.greenAccent,child: CustomPaint(foregroundPainter: _AnimationPainter(animation1),),),),),);}
}class _AnimationPainter extends CustomPainter {final Paint _paint = Paint();Animation? animation;_AnimationPainter(this.animation);@overridevoid paint(Canvas canvas, Size size) {_paint..color = Colors.redAccent..strokeWidth = 4..style = PaintingStyle.stroke;canvas.drawCircle(const Offset(100, 100), animation!.value * 1.5, _paint);}@overridebool shouldRepaint(CustomPainter oldDelegate) => true;
}


http://www.ppmy.cn/ops/144027.html

相关文章

wsl下Ubuntu(Linux)配置VSCode环境(C、C++)

一.vscode链接WSL 看我的另一篇博文&#xff1a; Vscode连接WSL2(Ubuntu20.04)_wsl2 vscode-CSDN博客 二.Linux系统配置c、c环境 和windows一样&#xff0c;要想使用C、C&#xff0c;要对系统环境进行配置&#xff0c;Linux是要安装gcc、g、gdb //可以用下面的代码在ubuntu…

uniapp实现手写签名,并在app中将其转为base64格式的图片

这里写自定义目录标题 1 手写签名页面&#xff1a;2 封装canvas组件&#xff1a;3 预览base64格式的签名图片&#xff1a; uniapp实现手写签名&#xff0c;并在app中将其转为base64格式的图片 1 手写签名页面&#xff1a; <template> <!-- 手写签名--><!-- &l…

基于 iAP2 协议 的指令协议,用于对安防设备的 MCU 进行操作

协议设计目标 1. 安全性&#xff1a;通过 iAP2 协议与 MCU 设备进行安全通信。 2. 通用性&#xff1a;支持对安防设备的常见功能进行操作&#xff0c;如状态查询、设备控制、参数配置等。 3. 高效性&#xff1a;数据结构简洁清晰&#xff0c;易于解析和扩展。 4. 扩展性&#x…

jenkins 出现 Jenkins: 403 No valid crumb was included in the request

文章目录 前言解决方式:1.跨站请求为找保护勾选"代理兼容"2.全局变量或者节点上添加环境变量3.&#xff08;可选&#xff09;下载插件 the strict Crumb Issuer plugin4.重启 前言 jenkins运行时间长了&#xff0c;经常出现点了好几次才能构建&#xff0c;然后报了Je…

【python】OpenCV—Image Moments

文章目录 1、功能描述2、图像矩3、代码实现4、效果展示5、完整代码6、涉及到的库函数cv2.moments 7、参考 1、功能描述 计算图像的矩&#xff0c;以质心为例 2、图像矩 什么叫图像的矩&#xff0c;在数字图像处理中有什么作用&#xff1f; - 谢博琛的回答 - 知乎 https://ww…

大模型技术优化负载均衡:AI驱动的智能化运维

在现代信息技术环境中&#xff0c;负载均衡是确保系统稳定、高效运行的关键技术。随着大模型技术&#xff08;Large Model Technology, LMT&#xff09;的发展&#xff0c;AI驱动的智能化负载均衡成为了优化系统性能、提升用户体验的重要手段。本文将详细介绍如何使用Python实现…

linux springboot项目启动端口被占用 Port 8901 was already in use.

....eb server failed to start. Port 8901 was already in use.Action:Identify and stop the process thats listening on port 8901 or configure this application to listen on another port.问题分析 这个错误表明端口 8901 已被其他进程占用。为了启动你的应用&#xf…

基于Spring Boot的新能源汽车个性化推荐系统

一、系统背景与意义 随着新能源汽车市场的快速发展&#xff0c;消费者对新能源汽车的需求日益多样化。为了满足消费者的个性化需求&#xff0c;提高购车体验&#xff0c;开发一个基于Spring Boot的新能源汽车个性化推荐系统显得尤为重要。该系统能够根据用户的偏好、历史行为等…