当前位置: 首页 > article >正文

Flutter 高级动画完全指南

Flutter 高级动画完全指南引言动画是提升用户体验的关键因素Flutter 提供了强大而灵活的动画系统。本文将深入探讨 Flutter 动画的高级特性包括自定义动画、复杂动画组合、性能优化等内容。动画基础回顾Flutter 中的动画主要分为两类补间动画Tween Animation在两个值之间平滑过渡物理动画Physics Animation模拟真实物理效果// 基础补间动画 AnimationController controller AnimationController( duration: Duration(seconds: 1), vsync: this, ); Animationdouble animation Tweendouble(begin: 0, end: 1).animate(controller);高级技巧一自定义 Tween创建自定义的补间动画可以实现更复杂的效果class ColorTween extends TweenColor { ColorTween({Color? begin, Color? end}) : super(begin: begin, end: end); override Color lerp(double t) { if (begin null || end null) return begin ?? end ?? Colors.transparent; return Color.fromARGB( lerpInt(begin!.alpha, end!.alpha, t), lerpInt(begin!.red, end!.red, t), lerpInt(begin!.green, end!.green, t), lerpInt(begin!.blue, end!.blue, t), ); } } // 使用自定义 Tween AnimationColor colorAnimation ColorTween( begin: Colors.blue, end: Colors.red, ).animate(controller);高级技巧二动画曲线与缓动函数Flutter 提供了丰富的动画曲线// 使用内置曲线 Animationdouble animation Tweendouble(begin: 0, end: 1).animate( CurvedAnimation( parent: controller, curve: Curves.easeInOut, ), ); // 自定义曲线 class CustomCurve extends Curve { override double transform(double t) { // 实现自定义缓动逻辑 return t * t * (3 - 2 * t); // 经典的 ease-out cubic } } // 组合曲线 Animationdouble combinedAnimation Tweendouble(begin: 0, end: 1).animate( CurvedAnimation( parent: controller, curve: Interval(0.2, 0.8, curve: Curves.bounceOut), ), );高级技巧三动画控制器进阶重复动画controller.repeat( min: 0, max: 1, reverse: true, period: Duration(seconds: 2), );动画监听animation.addListener(() { setState(() { // 更新 UI }); }); animation.addStatusListener((status) { if (status AnimationStatus.completed) { controller.reverse(); } else if (status AnimationStatus.dismissed) { controller.forward(); } });高级技巧四交错动画交错动画是指多个动画按顺序或重叠执行class StaggerAnimation extends StatelessWidget { final Animationdouble controller; late final Animationdouble opacity; late final Animationdouble width; late final Animationdouble height; late final AnimationEdgeInsets padding; StaggerAnimation({required this.controller}) { opacity Tweendouble(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.0, 0.100, curve: Curves.easeIn), ), ); width Tweendouble(begin: 50.0, end: 200.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.125, 0.250, curve: Curves.easeIn), ), ); height Tweendouble(begin: 50.0, end: 200.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.250, 0.375, curve: Curves.easeIn), ), ); padding EdgeInsetsTween( begin: const EdgeInsets.only(bottom: 16.0), end: const EdgeInsets.only(bottom: 75.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.250, 0.375, curve: Curves.easeIn), ), ); } Widget _buildAnimation(BuildContext context, Widget? child) { return Container( padding: padding.value, alignment: Alignment.bottomCenter, child: Opacity( opacity: opacity.value, child: Container( width: width.value, height: height.value, color: Colors.blue, ), ), ); } override Widget build(BuildContext context) { return AnimatedBuilder( animation: controller, builder: _buildAnimation, ); } }高级技巧五Hero 动画进阶Hero 动画用于页面间的元素过渡// 源页面 Hero( tag: imageHero, child: Image.network(https://example.com/image.jpg), ) // 目标页面 Hero( tag: imageHero, child: Image.network(https://example.com/image.jpg), ) // 自定义 Hero 动画 class CustomHero extends StatelessWidget { final Widget child; final String tag; const CustomHero({super.key, required this.child, required this.tag}); override Widget build(BuildContext context) { return Hero( tag: tag, createRectTween: (begin, end) { return CustomRectTween(begin: begin!, end: end!); }, child: child, ); } } class CustomRectTween extends RectTween { CustomRectTween({required super.begin, required super.end}); override Rect lerp(double t) { final curvedT Curves.easeInOut.transform(t); return Rect.lerp(begin, end, curvedT)!; } }高级技巧六物理动画物理动画模拟真实世界的物理效果// 弹簧动画 AnimationController springController AnimationController( vsync: this, duration: const Duration(seconds: 2), ); SpringSimulation spring SpringSimulation( SpringDescription( mass: 1.0, stiffness: 100.0, damping: 10.0, ), 0.0, // 起始值 1.0, // 结束值 0.0, // 初始速度 ); Animationdouble springAnimation springController.drive(spring); // 重力动画 GravitySimulation gravity GravitySimulation( 9.8, // 重力加速度 0.0, // 起始位置 100.0, // 结束位置 0.0, // 初始速度 );高级技巧七自定义绘制动画使用CustomPainter创建复杂的绘制动画class AnimatedCirclePainter extends CustomPainter { final Animationdouble animation; AnimatedCirclePainter({required this.animation}) : super(repaint: animation); override void paint(Canvas canvas, Size size) { final center Offset(size.width / 2, size.height / 2); final radius animation.value * min(size.width, size.height) / 2; Paint paint Paint() ..color Colors.blue ..style PaintingStyle.fill; canvas.drawCircle(center, radius, paint); // 添加发光效果 Paint glowPaint Paint() ..color Colors.blue.withOpacity(0.3) ..style PaintingStyle.stroke ..strokeWidth 4; canvas.drawCircle(center, radius 10 * animation.value, glowPaint); } override bool shouldRepaint(covariant CustomPainter oldDelegate) { return false; } } // 使用 AnimatedBuilder( animation: animation, builder: (context, child) { return CustomPaint( painter: AnimatedCirclePainter(animation: animation), size: Size(200, 200), ); }, )高级技巧八动画性能优化1. 使用RepaintBoundaryRepaintBoundary( child: AnimatedWidget(...), )2. 使用const构造函数// 避免不必要的重建 const Text(Hello, style: TextStyle(fontSize: 16));3. 使用AnimatedBuilderAnimatedBuilder( animation: animation, builder: (context, child) { return Transform.scale( scale: animation.value, child: child, // child 不会被重建 ); }, child: const Icon(Icons.star), )4. 避免在build方法中创建对象// 错误做法 Widget build(BuildContext context) { final animation Tweendouble(begin: 0, end: 1).animate(controller); return ...; } // 正确做法 late final Animationdouble animation; override void initState() { super.initState(); animation Tweendouble(begin: 0, end: 1).animate(controller); }实战案例复杂动画组件class FloatingButton extends StatefulWidget { const FloatingButton({super.key}); override StateFloatingButton createState() _FloatingButtonState(); } class _FloatingButtonState extends StateFloatingButton with SingleTickerProviderStateMixin { late AnimationController _controller; late Animationdouble _scaleAnimation; late Animationdouble _opacityAnimation; late AnimationOffset _slideAnimation; override void initState() { super.initState(); _controller AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); _scaleAnimation Tweendouble(begin: 0.8, end: 1.0).animate( CurvedAnimation(parent: _controller, curve: Curves.easeOutBack), ); _opacityAnimation Tweendouble(begin: 0.0, end: 1.0).animate( CurvedAnimation(parent: _controller, curve: Curves.easeIn), ); _slideAnimation TweenOffset( begin: const Offset(0, 20), end: Offset.zero, ).animate( CurvedAnimation(parent: _controller, curve: Curves.easeOut), ); // 延迟启动动画 Future.delayed(const Duration(milliseconds: 500), () { _controller.forward(); }); } override void dispose() { _controller.dispose(); super.dispose(); } override Widget build(BuildContext context) { return SlideTransition( position: _slideAnimation, child: FadeTransition( opacity: _opacityAnimation, child: ScaleTransition( scale: _scaleAnimation, child: FloatingActionButton( onPressed: () { _controller.reverse().then((_) { // 按钮点击后的逻辑 }); }, child: const Icon(Icons.add), ), ), ), ); } }实战案例粒子效果class Particle { double x; double y; double vx; double vy; double radius; Color color; Particle({ required this.x, required this.y, required this.vx, required this.vy, required this.radius, required this.color, }); } class ParticleSystem extends StatefulWidget { const ParticleSystem({super.key}); override StateParticleSystem createState() _ParticleSystemState(); } class _ParticleSystemState extends StateParticleSystem with SingleTickerProviderStateMixin { late AnimationController _controller; late ListParticle particles; override void initState() { super.initState(); _controller AnimationController( duration: const Duration(milliseconds: 16), vsync: this, )..repeat(); _initParticles(); _controller.addListener(() { _updateParticles(); }); } void _initParticles() { particles List.generate(50, (index) { return Particle( x: 200 Random().nextDouble() * 200, y: 200 Random().nextDouble() * 200, vx: (Random().nextDouble() - 0.5) * 2, vy: (Random().nextDouble() - 0.5) * 2, radius: Random().nextDouble() * 5 2, color: Colors.blue.withOpacity(Random().nextDouble() * 0.5 0.5), ); }); } void _updateParticles() { setState(() { for (var particle in particles) { particle.x particle.vx; particle.y particle.vy; // 边界检测 if (particle.x particle.radius || particle.x 400 - particle.radius) { particle.vx * -1; } if (particle.y particle.radius || particle.y 400 - particle.radius) { particle.vy * -1; } } }); } override void dispose() { _controller.dispose(); super.dispose(); } override Widget build(BuildContext context) { return CustomPaint( size: const Size(400, 400), painter: ParticlePainter(particles: particles), ); } } class ParticlePainter extends CustomPainter { final ListParticle particles; ParticlePainter({required this.particles}); override void paint(Canvas canvas, Size size) { for (var particle in particles) { Paint paint Paint()..color particle.color; canvas.drawCircle(Offset(particle.x, particle.y), particle.radius, paint); } } override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } }常见问题与解决方案Q1动画卡顿怎么办A检查是否有以下问题避免在动画中进行复杂计算使用RepaintBoundary隔离重绘区域考虑使用Transform代替PositionedQ2如何实现循环动画A使用controller.repeat()方法controller.repeat(reverse: true);Q3如何同步多个动画A使用同一个AnimationController驱动多个 Tweenfinal opacity Tweendouble(begin: 0, end: 1).animate(controller); final scale Tweendouble(begin: 0.5, end: 1).animate(controller);总结Flutter 的动画系统非常强大通过本文的学习你应该能够创建自定义 Tween 和曲线实现复杂的交错动画使用物理模拟创建真实感动画利用 CustomPainter 绘制自定义动画优化动画性能动画是提升应用体验的关键不断练习和尝试新的动画效果让你的应用更加生动有趣。

相关文章:

Flutter 高级动画完全指南

Flutter 高级动画完全指南 引言 动画是提升用户体验的关键因素,Flutter 提供了强大而灵活的动画系统。本文将深入探讨 Flutter 动画的高级特性,包括自定义动画、复杂动画组合、性能优化等内容。 动画基础回顾 Flutter 中的动画主要分为两类: …...

Nintendo Switch大气层系统:7步从零安装到精通优化完整指南

Nintendo Switch大气层系统:7步从零安装到精通优化完整指南 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 想要彻底释放你的Nintendo Switch游戏机潜力吗?Atmosphe…...

性能测试指标选不对,报告全白费!从一次线上故障复盘TPS、RT与吞吐量的关系

性能指标迷局:当高QPS掩盖了系统瓶颈的真相 那天凌晨三点,我被一阵急促的电话铃声惊醒。电商大促系统监控面板上QPS曲线依然漂亮,但业务方反馈用户下单延迟高达15秒——这个看似矛盾的场景,揭开了性能指标认知中最危险的陷阱。我…...

支付钱包启动器:架构设计与工程实践全解析

1. 项目概述:一个面向开发者的支付钱包启动器 最近在和一些做独立开发的朋友聊天,发现大家在做项目时,但凡涉及到支付、钱包这类功能,都挺头疼的。不是对接流程繁琐,就是安全风险高,要么就是代码耦合度太强…...

LeetCode 比特位计数题解

LeetCode 比特位计数题解 题目描述 给定一个非负整数 num,返回一个数组 answer,其中 answer[i] 表示 i 的二进制表示中 1 的个数。 示例: 输入:num 2输出:[0,1,1] 输入:num 5输出:[0,1,1…...

终极指南:用ncmdump彻底解决网易云音乐NCM格式限制

终极指南:用ncmdump彻底解决网易云音乐NCM格式限制 【免费下载链接】ncmdump ncmdump - 网易云音乐NCM转换 项目地址: https://gitcode.com/gh_mirrors/ncmdu/ncmdump 在数字音乐时代,格式兼容性已成为音乐爱好者面临的核心挑战。当你从网易云音乐…...

ViGEmBus虚拟游戏控制器驱动终极指南:Windows内核级游戏手柄模拟深度解析

ViGEmBus虚拟游戏控制器驱动终极指南:Windows内核级游戏手柄模拟深度解析 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 在Windows游戏开发与输…...

Flutter × Harmony6.0 打造高颜值优惠商城页面:跨端 UI 构建与组件化实践

Flutter Harmony6.0 打造高颜值优惠商城页面:跨端 UI 构建与组件化实践 前言 随着 HarmonyOS NEXT 与 Harmony6.0 生态逐渐成熟,越来越多开发者开始关注 Flutter 在鸿蒙平台上的跨端落地能力。相比传统 Android/iOS 双端分别维护的开发模式,…...

词源探秘|从orient到panorama:解码英语单词背后的文明密码

1. 从日出东方到现代导航:ori词根的文明之旅 当古人第一次观察到太阳从东方升起时,拉丁语用"oriri"(升起)记录这个现象。这个词根演变为ori,像一条暗线贯穿人类文明: orient(东方&a…...

基于 Harmony6.0 的优惠聚合应用实战:Flutter 页面构建与高质感 UI 设计解析

基于 Harmony6.0 的优惠聚合应用实战:Flutter 页面构建与高质感 UI 设计解析 前言 随着 HarmonyOS NEXT 与 Harmony6.0 生态逐渐成熟,越来越多开发者开始关注鸿蒙平台上的跨端开发方案。相比传统 Android 应用开发,Harmony6.0 更强调分布式能…...

告别远程桌面‘失忆症’:一招锁定xrdp端口,让你的XFCE会话永不丢失

告别远程桌面‘失忆症’:一招锁定xrdp端口,让你的XFCE会话永不丢失 远程办公和跨平台协作已成为现代开发者的日常,但当你正沉浸于代码世界时,突然的网络波动或客户端切换却让整个工作环境"人间蒸发"——这种经历恐怕每…...

ViGEmBus虚拟手柄驱动完全指南:Windows游戏手柄兼容性终极解决方案

ViGEmBus虚拟手柄驱动完全指南:Windows游戏手柄兼容性终极解决方案 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否厌倦了在Windows上使用…...

LaTeX2Word-Equation:打破学术写作中的公式壁垒

LaTeX2Word-Equation:打破学术写作中的公式壁垒 【免费下载链接】LaTeX2Word-Equation Copy LaTeX Equations as Word Equations, a Chrome Extension 项目地址: https://gitcode.com/gh_mirrors/la/LaTeX2Word-Equation 在学术研究和教育工作中,…...

静态页面构建优化:从核心技能到自动化部署实践

1. 项目概述:一个被低估的静态页面技能集 最近在整理自己的前端工具箱时,发现了一个挺有意思的仓库: jieshu666/ShipPage-Skill 。乍一看名字,你可能会觉得这又是一个关于“Ship”(部署)某个“Page”&…...

从电话语音到网络传输:手把手教你用C语言实现PCM与G.711(a-law/u-law)的互转

从电话语音到网络传输:手把手教你用C语言实现PCM与G.711(a-law/u-law)的互转 在嵌入式音视频开发中,音频编解码技术是构建高效通信系统的核心。当我们需要在资源受限的硬件平台上实现语音通话、对讲机或安防监控设备时&#xff0…...

开发者技能日志工具:用CLI与SQLite构建个人技术成长追踪系统

1. 项目概述:一个技能日志记录器的诞生 最近在整理自己的技术栈和项目经验时,我遇到了一个很多开发者都有的痛点:学了那么多东西,做了那么多项目,但真要写简历或者回顾成长路径时,记忆总是模糊的。今天学了…...

44《实车CAN总线报文ID含义与数据初步解读》

001、CAN总线基础与实车网络拓扑概述 从一次凌晨三点的“丢帧”说起 去年冬天,某主机厂的新能源车型在做冬季标定。凌晨三点,测试工程师打来电话,语气里带着疲惫和焦躁:“VCU发的车速信号,BMS偶尔收不到,但用CANoe监控又一切正常。”我赶到现场,第一件事不是看代码,而…...

5G有线网络标准化:从管道到智能融合基础设施的演进

1. 从“无线狂欢”到“有线觉醒”:5G标准化的另一面 如果你在2015年前后关注通信行业,印象最深刻的恐怕是各种关于5G的“炫技”新闻:毫米波、Massive MIMO、每秒数十Gb的峰值速率……整个行业仿佛陷入了一场关于“无线空口技术”的军备竞赛。…...

学生党福音:用最便宜的TT马达和STM32F103C8T6,我焊出了能遥控的平衡小车

低成本DIY平衡小车:TT马达与STM32的极致性价比方案 当我在宿舍里第一次看到那辆价值近千元的商业平衡小车时,脑海中立刻浮现出一个问题:能不能用更便宜的材料实现类似功能?作为一名预算有限的学生,我开始探索如何用最…...

Chopstick工具:高效管理多Git仓库的批量操作与自动化实践

1. 项目概述与核心价值 最近在GitHub上看到一个挺有意思的项目,叫 chopstick ,作者是DustinMeyer1010。光看名字你可能会联想到筷子,但它的实际功能跟餐具可没半点关系。这是一个专门用于 代码仓库(Repository)克隆…...

RoboMaster视觉入门:用OpenCV3.4.5从摄像头图像里找出装甲板(附完整C++代码)

RoboMaster视觉实战:从零构建装甲板识别系统(C/OpenCV3.4.5全解析) 在RoboMaster机甲大师赛中,视觉识别系统如同战车的"眼睛",而装甲板识别则是核心中的核心。本文将带你从零开始,用OpenCV3.4.5…...

3个秘籍解锁百度网盘提取码:告别繁琐搜索的智能解决方案

3个秘籍解锁百度网盘提取码:告别繁琐搜索的智能解决方案 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾在深夜急需下载学习资料,却被一个简单的提取码困住?或者在工作汇报前&#…...

3个技巧彻底改变你的泰坦之旅装备管理体验

3个技巧彻底改变你的泰坦之旅装备管理体验 【免费下载链接】TQVaultAE Extra bank space for Titan Quest Anniversary Edition 项目地址: https://gitcode.com/gh_mirrors/tq/TQVaultAE 你是否曾在泰坦之旅的冒险中,面对满仓库的传奇装备却找不到需要的那一…...

光子计算如何突破LLM推理中的KV缓存瓶颈

1. 光子计算在KV缓存管理中的突破性应用在当今大语言模型(LLM)推理领域,一个令人惊讶的事实正在发生:计算能力已不再是主要瓶颈。随着上下文窗口从最初的几千token扩展到如今的百万级(如Qwen2.5)&#xff0…...

ubuntu 快捷键和常用命令

在使用 ubuntu 作为主机后,对于一些常见的操作,需要更加快捷的方式执行,这也是我选择 ubuntu 的主要原因。这篇文章手机 ubuntu 的快捷键和一些常用的命令。 快捷键 f2是重命名 linux控制台快捷键 ctrl a e CtrlShiftn 新终端 ShiftCt…...

WinForm + Modbus 上位机温湿度数据采集系统

前言工业自动化和环境监控领域,实时掌握现场的温湿度数据至关重要。传统的监控方式往往依赖人工记录或简单的报警装置,缺乏直观性和连续性。本文推荐一个基于WinForm开发的上位机温湿度采集系统,通过Modbus通信协议与下位机进行数据交互&…...

3分钟极速指南:网易云音乐无损FLAC批量下载神器

3分钟极速指南:网易云音乐无损FLAC批量下载神器 【免费下载链接】NeteaseCloudMusicFlac 根据网易云音乐的歌单, 下载flac无损音乐到本地.。 项目地址: https://gitcode.com/gh_mirrors/nete/NeteaseCloudMusicFlac 还在为寻找高品质音乐资源而烦恼吗&#x…...

AI代理协作平台Run402:基于看板与微支付的自动化任务管理

1. 项目概述:一个面向AI代理的协作与支付平台最近在开源社区里,我注意到一个挺有意思的项目,叫musfoner/run402。乍一看,它的描述非常简洁,甚至可以说有些“神秘”,只有“yonathan estudio”几个字。但结合…...

Sonixd多语言支持详解:国际化(i18n)实现原理和本地化最佳实践

Sonixd多语言支持详解:国际化(i18n)实现原理和本地化最佳实践 【免费下载链接】sonixd A full-featured Subsonic/Jellyfin compatible desktop music player 项目地址: https://gitcode.com/gh_mirrors/so/sonixd Sonixd是一款功能强大的桌面音乐播放器&…...

终极ncmdump指南:如何快速破解网易云音乐NCM加密格式限制

终极ncmdump指南:如何快速破解网易云音乐NCM加密格式限制 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾为网易云音乐下载的NCM格式文件无法在其他播放器中播放而烦恼?ncmdump作为一款开源解密工具&…...