ListWheelScrollView卡顿求助:慢速滚动时界面冻结无响应
核心原因分析
未使用懒加载机制
你当前直接通过controller.events.map()一次性生成所有子组件,当events数据量较大时,会瞬间创建所有组件实例,占用大量内存和CPU资源,滚动时自然会出现卡顿甚至冻结。ListWheelScrollView专门提供了itemBuilder懒加载方案,只会创建当前可见区域及少量预加载的组件,能大幅降低性能开销。子组件频繁无意义重建
你的EasyContainer以及内部嵌套的Column、Row等组件,在滚动过程中可能被频繁重建。如果Event对象没有正确重写==和hashCode方法,或者可使用const构造器的组件未添加const修饰,都会触发不必要的组件重建,加重渲染负担。实时翻译操作的性能损耗
代码中event.eventType!.tr的翻译操作,如果是每次组件build时都实时执行(未缓存翻译结果),会在滚动过程中持续消耗资源,拖慢滚动流畅度。自定义容器的绘制开销
EasyContainer作为自定义容器,它的阴影、边框、圆角等样式如果未做优化(比如阴影效果过于复杂、裁剪方式低效),会增加每帧的绘制时间,导致滚动卡顿。
对应解决办法
改用懒加载的itemBuilder
替换成ListWheelScrollView.useDelegate配合ListWheelChildBuilderDelegate实现懒加载:ListWheelScrollView.useDelegate( itemExtent: 250, diameterRatio: 5, childDelegate: ListWheelChildBuilderDelegate( builder: (context, index) { final event = controller.events[index]; return EasyContainer( margin: 10, color: Colors.white, shadowColor: Colors.black, borderColor: Colors.blueGrey, borderStyle: BorderStyle.solid, borderWidth: 1, borderRadius: 10, showBorder: true, onTap: () => Get.to(() => const EventDetailsScreen()), child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ Row( children: [ const Icon(Icons.star, color: Colors.yellow), const Expanded(child: SizedBox()), Text(event.eventType!.tr), // 剩余组件代码... ], ), // 剩余组件代码... ], ), ), ); }, childCount: controller.events.length, ), )优化组件重建逻辑
- 给
Event类重写==和hashCode方法,或使用freezed等库生成不可变对象,确保组件能正确判断是否需要重建。 - 对所有可使用
const的组件添加const修饰,减少不必要的实例创建。 - 如果子组件需要保留状态,让其混入
AutomaticKeepAliveClientMixin,避免滚动时销毁重建。
- 给
缓存翻译结果
在获取events数据时,提前将eventType的翻译结果缓存到Event对象中,不要在组件build阶段实时调用tr方法。优化自定义容器绘制
- 检查
EasyContainer内部的阴影、圆角等实现,使用Clip.hardEdge提升裁剪效率,或在非必要时关闭阴影效果。
- 检查
内容的提问来源于stack exchange,提问作者skm

