使用ListWheelScrollView搭配动画组件时Flutter应用卡顿问题
解决ListWheelScrollView搭配CircularProgressIndicator导致的Flutter卡顿问题
问题分析
这个卡顿是ListWheelScrollView的持续渲染计算与CircularProgressIndicator的帧动画更新冲突导致的。ListWheelScrollView会后台持续计算子组件的布局和透视变换,而CircularProgressIndicator的每帧动画都会触发重绘,两者叠加后会在数分钟内耗尽渲染资源,直接导致帧率暴跌至0.1左右,且调试/发布包、模拟器等全环境都存在该问题。
可行解决方案
- 用
RepaintBoundary隔离动画组件
把CircularProgressIndicator包裹在RepaintBoundary中,避免其动画触发整个页面的重绘:
// 修改TestPage代码 Expanded(child: Listview()), RepaintBoundary( child: CircularProgressIndicator(), )
- 优化ListWheelScrollView子组件复用
确保子组件不会无意义重绘,可给子组件添加唯一标识,帮助Flutter复用组件:
// 修改ListWheelScrollView的子组件生成逻辑 children: List.generate(50, (index){ return Container( key: ValueKey(index), width: 250, decoration: const BoxDecoration( color: Colors.grey, border: Border.all(width: 1.0, color: Colors.blue) ), child: Text("$index") ); }),
替换ListWheelScrollView(场景允许时)
如果交互场景可替代,改用ListView搭配自定义滚动效果,避免ListWheelScrollView的持续计算开销。升级Flutter SDK
部分旧版本Flutter存在类似渲染性能bug,升级至最新稳定版可能自动修复问题。
问题复现代码
class TestPage extends StatelessWidget { const TestPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded(child: Listview()), CircularProgressIndicator() ], ), ); } }
class Listview extends StatelessWidget { const Listview({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return ListWheelScrollView( physics: FixedExtentScrollPhysics(), children: List.generate(50, (index){ return Container( width: 250, decoration: BoxDecoration( color: Colors.grey, border: Border.all(width: 1.0, color: Colors.blue) ), child: Text("$index") ); }), itemExtent: 50, ); } }
内容的提问来源于stack exchange,提问作者sunkim
相关产品推荐
相关产品推荐

