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

五、Flutter动画

目录

  • 1. Flutter 中动画的基本概念是什么?
  • 2. 解释 AnimationController 和 Tween 的作用
  • 3. 如何实现一个补间(Tween)动画?
  • 4. 什么是隐式动画?举例说明
  • 5. 如何实现自定义复杂动画?

1. Flutter 中动画的基本概念是什么?

在 Flutter 中,动画是通过在一段时间内连续改变属性值来实现的视觉效果变化。核心概念包括:

概念说明
动画值随时间变化的数值(通常是 0.0 → 1.0)
动画控制器管理动画的播放、停止、反转等操作
补间 (Tween)定义起始值和结束值之间的过渡(如位置、大小、颜色等)
动画曲线控制动画变化速率(如加速、减速、弹跳等)
动画监听器在动画值变化时更新 UI
动画状态运行中 (forward)、完成 (completed)、反转中 (reverse)、停止 (dismissed)

动画分类

  • 隐式动画:自动处理的简单动画(如 AnimatedContainer
  • 显式动画:需要手动控制的复杂动画(使用 AnimationController

2. 解释 AnimationController 和 Tween 的作用

AnimationController

  • 作用:管理动画的播放状态和持续时间
  • 特点
    • 需要 TickerProvide*(如 SingleTickerProviderStateMixin
    • 默认输出 0.0 → 1.0 的值
    • 控制动画播放 (forward())、停止 (stop())、反转 (reverse())
  • 创建
late AnimationController _controller;
void initState() {super.initState();_controller = AnimationController(duration: const Duration(seconds: 2),  // 动画时长vsync: this,  // 使用 TickerProvider);
}

Tween

  • 作用:定义动画的值范围(如颜色、大小、位置等)
  • 特点
    • 将 0.0→1.0 映射到实际值范围
    • 支持多种数据类型(ColorTwee*, SizeTween 等)
  • 使用
final Animation<double> _sizeAnim = Tween<double>(begin: 50.0, end: 200.0,
).animate(_controller);

3. 如何实现一个补间(Tween)动画?

步骤

  1. 创建 AnimationController
  2. 定义 Tween 并绑定控制器
  3. 添加监听器重建 UI
  4. 启动动画

示例代码

class TweenAnimationDemo extends StatefulWidget {_TweenAnimationDemoState createState() => _TweenAnimationDemoState();
}class _TweenAnimationDemoState extends State<TweenAnimationDemo> with SingleTickerProviderStateMixin {late AnimationController _controller;late Animation<double> _sizeAnim;late Animation<Color?> _colorAnim;void initState() {super.initState();// 1. 创建控制器_controller = AnimationController(duration: const Duration(seconds: 2),vsync: this,)..repeat(reverse: true); // 循环播放// 2. 创建补间动画_sizeAnim = Tween<double>(begin: 50, end: 200).animate(_controller);_colorAnim = ColorTween(begin: Colors.blue, end: Colors.red).animate(_controller);}Widget build(BuildContext context) {// 3. 使用 AnimatedBuilder 优化性能return AnimatedBuilder(animation: _controller,builder: (context, child) {return Center(child: Container(width: _sizeAnim.value,height: _sizeAnim.value,color: _colorAnim.value,),);},);}void dispose() {_controller.dispose(); // 释放资源super.dispose();}
}

4. 什么是隐式动画?举例说明

隐式动画:只需设置目标值,Flutter 自动处理动画过程的简化动画。

特点

  • 无需管理 AnimationController
  • 内置 300ms 默认动画时长
  • 通过 setState() 改变属性值自动触发

常用隐式动画组件

组件作用
AnimatedContainer容器属性变化(大小/颜色等)
AnimatedOpacity透明度变化
AnimatedPositioned位置变化(Stack 内)
AnimatedAlign对齐方式变化

示例:点击改变容器大小和颜色

class ImplicitAnimationDemo extends StatefulWidget {_ImplicitAnimationDemoState createState() => _ImplicitAnimationDemoState();
}class _ImplicitAnimationDemoState extends State<ImplicitAnimationDemo> {double _size = 100;Color _color = Colors.blue;void _animate() {setState(() {_size = _size == 100 ? 200 : 100;_color = _color == Colors.blue ? Colors.green : Colors.blue;});}Widget build(BuildContext context) {return GestureDetector(onTap: _animate,child: AnimatedContainer(duration: Duration(seconds: 1), // 动画时长width: _size,height: _size,color: _color,curve: Curves.easeInOut, // 动画曲线child: Center(child: Text('点击我')),),);}
}

5. 如何实现自定义复杂动画?

对于复杂动画(如路径动画、物理动画、多动画同步),推荐使用:

1. 组合多个动画

late Animation<double> _sizeAnim;
late Animation<double> _rotationAnim;
void initState() {super.initState();_sizeAnim = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: _controller,curve: Interval(0.0, 0.5), // 只在前半段执行),);_rotationAnim = Tween(begin: 0.0, end: 2 * pi).animate(CurvedAnimation(parent: _controller,curve: Interval(0.5, 1.0), // 只在后半段执行),);
}

2. 使用物理动画(SpringSimulation)

void _runSpringAnimation() {final spring = SpringSimulation(SpringDescription(mass: 1, stiffness: 100, damping: 10),0.0,   // 起始位置300.0, // 目标位置10.0,  // 初始速度);_controller.animateWith(spring);
}

3. 自定义动画曲线

final customCurve = CurveTween(curve: Curves.easeInOutBack,
);_animation = customCurve.animate(_controller);

4. 使用动画状态机

_controller.addStatusListener((status) {if (status == AnimationStatus.completed) {_controller.reverse();} else if (status == AnimationStatus.dismissed) {_controller.forward();}
});

完整示例:弹跳球效果

class BouncingBallDemo extends StatefulWidget {_BouncingBallDemoState createState() => _BouncingBallDemoState();
}class _BouncingBallDemoState extends State<BouncingBallDemo>with SingleTickerProviderStateMixin {late AnimationController _controller;late Animation<double> _bounceAnim;void initState() {super.initState();_controller = AnimationController(duration: const Duration(seconds: 2),vsync: this,)..repeat(reverse: true);// 使用弹性曲线模拟弹跳_bounceAnim = Tween<double>(begin: 0, end: 300).animate(CurvedAnimation(parent: _controller,curve: Curves.elasticOut, // 弹性效果),);}Widget build(BuildContext context) {return AnimatedBuilder(animation: _controller,builder: (context, child) {return Stack(children: [Positioned(bottom: _bounceAnim.value,left: MediaQuery.of(context).size.width / 2 - 25,child: Container(width: 50,height: 50,decoration: BoxDecoration(color: Colors.red,shape: BoxShape.circle,),),),],);},);}
}
http://www.lryc.cn/news/579969.html

相关文章:

  • 【AI总结】Git vs GitHub vs GitLab:深度解析三者联系与核心区别
  • 【Git】git命令合集
  • 网安系列【4】之OWASP与OWASP Top 10:Web安全入门指南
  • Rust 闭包
  • 暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目
  • 封装一个png的编码解码操作
  • 数据库位函数:原理、应用与性能优化
  • 企业该怎么做竞争分析?一文了解
  • Linux-进程概念(3)
  • 【WEB】Polar靶场 6-10题 详细笔记
  • 类图+案例+代码详解:软件设计模式----原型模式
  • vue3 el-table 行筛选 设置为单选
  • 电商分拣的“效率密码”:艾立泰轻量化托盘引领自动化流水线革新
  • vue3 获取选中的el-table行数据
  • 【WRFDA第三期】OBSPROC namelist 变量总结
  • Ubuntu 22.04 + MySQL 8 无密码登录问题与 root 密码重置指南
  • OpenCV中DPM(Deformable Part Model)目标检测类cv::dpm::DPMDetector
  • 前端基础知识Webpack系列 - 03(webpack中常见的Loader?解决了什么问题?)
  • STM32CubeMX教程1 实现点灯点灯
  • 量化开发(系列第3篇): C++在高性能量化交易中的核心应用与技术栈深度解析
  • 三态逻辑详解:单片机GPIO、计算机总线系统举例
  • 【python实用小脚本-128】基于 Python 的 Hacker News 爬虫工具:自动化抓取新闻数据
  • RK-Android11-性能优化-限制App内存上限默认512m
  • 基于Hadoop的公共自行车数据分布式存储和计算平台的设计与实现
  • 如何调节笔记本电脑亮度?其实有很多种方式可以调整亮度
  • Mysql+neo4j创建节点和关系
  • [环境安装] 图数据库Neo4j 2025.05 安装(apple M芯片)
  • XILINX Kintex 7系列FPGA的全局时钟缓冲器(BUFG)和区域时钟缓冲器(BUFR/BUFH)的区别
  • EPLAN 电气制图:建立自己的部件库,添加部件-加SQL Server安装教程(三)上
  • HarmonyOS学习记录3