Flutter组合动画学习

如何使用动画控制器和动画来创建一个简单的动画效果。具体来说,它通过一个 `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 MyAnimaDemoPage extends StatefulWidget {const MyAnimaDemoPage({super.key});@override_MyAnimaDemoPageState createState() {return _MyAnimaDemoPageState();}
}class _MyAnimaDemoPageState extends State<MyAnimaDemoPage>with SingleTickerProviderStateMixin {late AnimationController controller1;late Animation animation2;Animation? animation1;@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.blue,child: CustomPaint(foregroundPainter: _MyAnimationPainter(animation1),),),),),);}
}class _MyAnimationPainter extends CustomPainter {final Paint _paint = Paint();Animation? animation;_MyAnimationPainter(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(covariant CustomPainter oldDelegate) {return true;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在vscode的ESP-IDF中使用自定义组件

以hello-world为例&#xff0c;演示步骤和注意事项 1、新建ESP-IDF项目 选择模板 从hello-world模板创建 2、打开项目 3、编译结果没错 正在执行任务: /home/azhu/.espressif/python_env/idf5.1_py3.10_env/bin/python /home/azhu/esp/v5.1/esp-idf/tools/idf_size.py /home…

2025差旅平台怎么选?一体化、全流程降本案例解析

差旅支出在企业中一直是一项重要但容易被忽视的成本开支&#xff0c;尤其是在项目驱动型企业中&#xff0c;因频繁的差旅需求&#xff0c;支出规模往往持续增长。以差旅平台分贝通签约伙伴——某智能制造业的业务模式为例&#xff0c;该模式要求员工定期前往不同的工厂、供应商…

【linux】NFS实验

NFS NFS服务 nfs,最早是Sun这家公司所发展出来的,它最大的功能就是可以透过网络,让不同的机器,不同的操作系统,进行实现文档的共享。所以你可以简单的将他看做是文件服务器。 实验准备 ①先准备一个服务器端的操作系统和客户端的操作系统(Red Hat)。 ②选择NAT模式,…

智源研究院与安谋科技达成战略合作,共建开源AI“芯”生态

12月25日&#xff0c;智源研究院与安谋科技&#xff08;中国&#xff09;有限公司&#xff08;以下简称“安谋科技”&#xff09;与正式签署战略合作协议&#xff0c;双方将面向多元AI芯片领域开展算子库优化与适配、编译器与工具链支持、生态系统建设与推广等一系列深入合作&a…

ROG NUC:强大内核激发创意,AI赋能学子科技探索

有这么一款能够激发无限创意、助力科技探索的迷你主机&#xff0c;它以其卓越的性能和迷你的身材成为了成为了ProArt百校行活动中的明星产品&#xff0c;助力广大学子勇敢探索未知&#xff0c;追逐属于自己的科技梦想。它就是ROG NUC 2024&#xff01; 强大性能&#xff0c;创意…

从零玩转CanMV-K230(8)-多线程例程

文章目录 前言一、_thread模块API二、使用示例创建并启动线程停止线程_thread.exit() 总结 前言 K230上不支持threading&#xff0c;只能支持_thread&#xff0c;该模块实现了相应 CPython 模块的子集&#xff0c;CPython 是 Python 编程的参考实现 语言&#xff0c;也是最著名…

yii2 手动添加 phpoffice\phpexcel

1.下载地址&#xff1a;https://github.com/PHPOffice/PHPExcel 2.解压并修改文件名为phpexcel 在yii项目的vendor目录下创建一个文件夹命名为phpoffice 把phpexcel目录放到phpoffic文件夹下 查看vendor\phpoffice\phpexcel目录下会看到这些文件 3.到vendor\composer目录下…

安卓多渠道apk配置不同签名

一般签名都是放在buildTypes里面&#xff1a; ... android {...defaultConfig {...}signingConfigs {release {storeFile file("myreleasekey.keystore")storePassword "password"keyAlias "MyReleaseKey"keyPassword "password"}}bu…

数据库-用户管理

一、创建用户 create user xy104192..168.42.24 identified by 123456;xy104&#xff1a;用户名 localhost&#xff1b;这个权限最高的root用户 %&#xff1a;任务ip地址 192.168.42.24&#xff1a;登录的IP地址 identified by ‘123456’&#xff1a;指定该用户的密码 mysql…

管理者需要的技能

管理者需要具备技术技能、人际技能和概念技能&#xff0c;这三种技能的内涵如下&#xff1a; 技术技能 专业知识与技术能力&#xff1a;指管理者掌握和运用某一专业领域内的知识、技术和方法的能力。这包括对特定行业的专业知识、技术流程、工具设备的熟悉和精通。例如&#x…

scala基础学习(数据类型)-字符串

文章目录 scala中的字符串引号单引号双引号三引号 常用内置函数length 获取字符串长度charAt 字符串元素访问substring 获取字串indexOf 获取字串位置replace 字符串替换toLowerCase,toUpperCase 字符串大小写转换trim 去除首位空白符split 字符串切割以及查看startsWith,endsW…

数据库安全-redisCouchdb

1.redis未授权访问 默认端口:6379 1.1 Redis沙盒逃逸漏洞RCE-CVE-2022-0543 介绍&#xff1a;Redis 是一套开源的使用 ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值存储数据库&#xff0c;并提供多种语言的API。Redis 如果在没有开启认证的情况下&#xff0c;…

springboot集成websokcet+uniapp开发聊天原型验证(一)

1. 整体思路 群组聊天功能实现思路 需要为每个群组维护一个对应的集合&#xff08;可以是 Set 等数据结构&#xff09;&#xff0c;用来存放该群组内所有在线用户的 WebSocketSession。当有消息发送到群组时&#xff0c;遍历该群组对应的集合&#xff0c;向其中的每个在线用户…

Reed-Muller(RM)码之编码

点个关注吧! 看了一些中文的博客,RM码没有很详细的资料,所以本文尝试给出推导原理。 推导 RM码由 ( r , m ) ( r , m ) (r,m

List直接使用removeAll报错

List直接使用removeAll报错 需要先将list转换才能使用 原因是&#xff1a; removeAll 方法在 Java 中用于从当前列表中删除另一个列表中存在的所有元素。如果直接对 List 接口的一个实现使用 removeAll 方法抛出异常&#xff0c;可能的原因有&#xff1a; 不同的List实现&am…

Linux -- 线程的优点、pthread 线程库

目录 线程的优点 pthread 线程库 前言 认识线程库 简单验证线程的独立栈空间 线程的优点 与进程之间的切换相比&#xff0c;线程之间的切换需要操作系统做的工作要少得多。 调度进程时&#xff0c;CPU 中有一个 cache&#xff08;缓存&#xff0c;提高运行效率&#xff0…

【magic-dash】01:magic-dash创建单页面应用及二次开发

文章目录 一、magic-dash是什么1.1 安装1.2 使用1.2.1 查看内置项目模板1.2.2 生成指定项目模板1.2.3 查看当前magic-dash版本1.2.4 查看命令说明1.2.5 内置模板列表二、创建虚拟环境并安装magic-dash三、magic-dash单页工具应用开发3.1 创建单页面项目3.1.1 使用命令行创建单页…

从零开始使用MaxKB打造本地大语言模型智能问答系统与远程交互

文章目录 前言1. 下载运行Ollama2. 安装大语言模型3. 安装Cpolar工具4. 配置公网地址5. 固定公网地址6. MaxKB 添加Olama7.创建问答应用 前言 目前大语言模型&#xff08;LLM&#xff09;已经成为了人工智能领域的一颗璀璨明星&#xff0c;从自然语言处理到智能问答系统&#…

深度解析 Pytest 中的 conftest.py

关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理&#xff0c;构建成功的基石 在自动化测试工作之前&#xff0c;你应该知道的10条建议 在自动化测试中&#xff0c;重要的不是工具 在使用 Pytest 进行测试的过程中&#xff0c;conftest.py 文件扮演着极为重要的角色…

【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割

数据预处理 通过网盘分享的文件&#xff1a;银行流失预测数据和代码 链接: https://pan.baidu.com/s/1loiB8rMvZArfjJccu4KW6w?pwdpfcs 提取码: pfcs 非数值特征处理 目的&#xff1a;将非数值特征转换为数值型&#xff0c;以便模型能够处理。方法&#xff1a; 地理位置&am…