返回
抛弃 setState,拥抱 Flutter 动画的新时代
Android
2023-10-19 11:44:41
告别 setState,拥抱 Flutter 动画新时代
在 Flutter 的世界中,动画一直是一个必不可少的元素,它赋予了我们的应用程序生命力。然而,传统的 setState() 方法可能限制了我们的创造力,并带来了性能问题。现在是时候拥抱 Flutter 动画的新时代了,探索更有效的方法来管理和优化你的动画。
动画生命周期
让我们从了解动画生命周期开始。每当界面发生变化时,都会触发一帧更新。这一系列更新包括:
- Animate: 计算动画值的变化。
- Build: 基于动画值重新构建小部件树。
- Layout: 确定小部件在屏幕上的位置和大小。
- Compositing bits: 将小部件组合成位图。
- Paint: 将位图绘制到屏幕上。
- Compositing: 将位图与其他层合成。
当左侧 UI 时间过高时,表明你的界面存在问题。例如:
一帧触发 | UI 时间(左) | 光栅时间(右)
------- | -------- | ----------
1 | 16.67ms | 16.67ms
2 | 16.67ms | 16.67ms
...
4 | 66.67ms | 16.67ms
5 | 16.67ms | 16.67ms
...
在上面的示例中,当第四帧发生时,UI 时间突然飙升至 66.67ms,而光栅时间保持不变。这表明在第四帧中存在一些开销,导致 UI 渲染时间过长。
优化动画性能
要优化动画性能,我们需要关注以下关键点:
- 使用 Animate(): Animate() 方法仅在动画值发生变化时触发,避免了不必要的重建。
- 批处理更新: 使用 Future.wait() 或 SchedulerBinding.addPostFrameCallback() 批处理多个更新,减少重建次数。
- 使用 AnimatedBuilder: AnimatedBuilder 小部件可以让你在动画值发生变化时仅重建受影响的部分,而不是整个小部件树。
- 使用 AnimatedValue: AnimatedValue 提供了一个可观察的动画值,可以在其值发生变化时自动更新 UI。
案例研究:从 setState() 到 Animate()
让我们以一个实际示例来说明这些技术的好处。以下是如何使用 setState() 实现一个简单的动画:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
double _progress = 0.0;
@override
Widget build(BuildContext context) {
return Column(
children: [
LinearProgressIndicator(value: _progress),
ElevatedButton(
onPressed: () {
setState(() {
_progress += 0.1;
});
},
child: Text('Update'),
),
],
);
}
}
使用 Animate(),我们可以显著优化性能:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
final ValueNotifier<double> _progress = ValueNotifier(0.0);
@override
Widget build(BuildContext context) {
return Column(
children: [
LinearProgressIndicator(value: _progress.value),
ElevatedButton(
onPressed: () {
_progress.value += 0.1;
},
child: Text('Update'),
),
],
);
}
}
通过使用 ValueNotifier,我们避免了不必要的重建,因为只有当 _progress.value 发生变化时才触发构建。
结论
告别 setState(),拥抱 Flutter 动画的新时代。通过利用 Animate()、Build、Layout 和其他优化技术,我们可以创建流畅、响应迅速且高效的动画。告别性能瓶颈,让你的应用程序在移动设备上尽情绽放。