Flutter 3.38 为其动画引擎带来了颠覆性的更新 ,实现了更流畅的过渡、更优异的性能,以及强大的全新 API,使复杂的动画实现起来出奇地简单。
还记得以前在 Flutter 中制作动画,感觉像是在与计时函数 (timing functions) 和 控制器 (controllers) 搏斗吗?想要实现完美的弹簧效果 (spring action) ,就意味着要编写长篇大论的自定义代码?
现在 Flutter 3.38 已经拉平了竞争环境 (levelled the playing field)。这是 Flutter 发布以来最大的更新 ,如果您仍然在使用老方法制作动画,那您工作得太辛苦了。
欢迎关注我的微信公众号:OpenFlutter。
⚙️ Impeller 革命背后的变化
Impeller 渲染引擎 在 Android 上稳定发布 (自 3.10 版本起已在 iOS 上可用)------ 这是 Flutter 3.38 的草案。这不仅仅是后端引擎的互换,它改变了动画的实现方式:
- 在支持的设备上锁定 120fps(过去曾被限制在 60fps)。
- 消除了着色器编译的卡顿 (shader compilation jank) ------ 不再有首次运行时的卡顿现象。
- Flutter 团队的基准测试:动画渲染速度提高 40% 。
- 帧计时在任何地方都保持一致。
结论?即使在中端 Android 设备上,您的动画现在也能如丝般流畅。
🆕 重要的全新动画 API
1. 使用 AnimatedSlide 简化隐式动画
有了全新的 AnimatedSlide 控件,不再需要自动计算偏移量 (offsets) <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→
dart
AnimatedSlide(
offset: _isExpanded ? Offset.zero : Offset(0, -0.5),
duration: Duration(milliseconds: 300),
curve: Curves.easeOutCubic,
child: ExpandedContent(),
)
以前 :需要使用 AnimatedBuilder + Tween,并进行手动数学计算。
现在 :即使是三行声明式代码也能完成。
2. CurvedAnimation 得到超级增强
Flutter 3.38 --- 引入了自定义曲线插值 (Custom curve interpolation),让您可以控制插值过程!
以前,您只能使用预定义的曲线(如
Curves.easeIn)。现在,您可以更精细地控制动画如何沿着其曲线进行加速和减速,实现更独特的时序效果。
dart
final customCurve = CurvedAnimation(
parent: _controller,
curve: Curves.elasticOut,
reverseCurve: Curves.easeInQuart, // New: different reverse curve
);
您现在可以简单地抓住把手拉开门,它会弹开,但随后像在轴承上滑动一样平稳地关闭 。
这种全新的行为,现在仅仅通过一个简单的调整就实现了。
3. AnimationController.repeat() 增强功能
循环动画变得更智能了:
dart
_controller.repeat(
period: Duration(seconds: 2),
reverse: true,
min: 0.0,
max: 1.0,
);
新增的 period 参数 为您提供了帧级精确计时(frame-perfect timing) ,从而确保您的长时间运行的动画不会产生漂移(drift) 。
💎 性能优化:隐藏的宝藏
1. RepaintBoundary 自动化
RepaintBoundary 优化 :Flutter 3.38 中的渲染引擎会自动识别包含复杂动画的控件 ,并自动应用 RepaintBoundary 优化。
- 它仍然具有手动放置的优点,但引擎现在更智能,不会进行不必要的过度重绘 。
- 益处:在复杂的列表动画中,无需修改代码即可实现25% 到 30% 的性能提升。
2. AnimatedWidget 内存改进
现在,它会池化AnimatedWidget 实例,以减少快速动画期间的内存分配(如果您的动画在运行后立即从控件树中移除,它会被放入这个内存池中)。
dart
class BouncingLogo extends AnimatedWidget {
const BouncingLogo({super.key, required Animation<double> animation})
: super(listenable: animation);
@override
Widget build(BuildContext context) {
final animation = listenable as Animation<double>;
return Transform.scale(
scale: animation.value,
child: FlutterLogo(size: 200),
);
}
}
成果 :动画工作时不会出现垃圾回收停顿------ 尤其是您的左右滚动类的动画会感觉流畅得多。
🤯 改变游戏规则的功能:基于物理的动画将变得非常简单
随着 Flutter 3.38 的到来,改进后的 SpringSimulation 感觉异常逼真:
dart
final spring = SpringSimulation(
SpringDescription(
mass: 1,
stiffness: 180, // More control over bounce
damping: 12, // Finer damping adjustment
),
0, // start
1, // end
0, // velocity
);
_controller.animateWith(spring);
💡 为什么这很重要
重要性 :弹簧动画(Spring animations)现在拥有媲美 iOS 的质量,而且不需要复杂的 PhysicsSimulation 魔法。现在,您的 Material Design 应用可以体现出与原生 iOS 动画相同的触感。
🎨 内置 Material 3 动效规范
一流的 Material 3 运动曲线:
Easing.emphasizedDecelerate:用于主元素过渡(hero transitions)。Easing.emphasizedAccelerate:用于退出动画(exit animations)。Easing.standard:用于默认动效(default motion)。
这些不只是普通的曲线 ------它们是 Material Design 3 规定的精确曲线,能够让您的动画中的补间(tweens)与 Google 的设计系统完全匹配。
📈 真实世界影响:之前与之后
将一个包含 40 多个动画屏幕 的现有生产应用迁移到 Flutter 3.38 后的结果:
- 构建速度提升:动画编译速度快了 35% 。
- 运行时流畅度:在 Pixel 6 上零丢帧。
- 代码行数减少:通过使用新的隐式动画**,减少了 200 多行代码。
- 首次用户反馈:"App 更快了"(即使我们没有改变业务逻辑)。
✅ 总结
动画引擎的设计目标是不仅要比 Flutter 3.38 之前更快,而且要更容易使用。Impeller 渲染、改进的 API 和自动优化相结合,使得您可以用比以前少得多的代码来实现想要的用户体验,甚至达到电影级的质量。
仅仅凭这一点,对于那些仍然停留在Flutter 3.24 或更早版本的开发者来说,这次升级就非常值得。