customizable_multiselect_field大列表卡顿延迟问题优化求助
解决customizable_multiselect_field大数据量卡顿问题
核心原因
当前使用的customizable_multiselect_field 1.0.1默认会一次性渲染所有列表项,当数据量达到600+时,大量Widget的同步创建与渲染会直接导致弹窗打开延迟、滚动卡顿。
解决方案
1. 优先尝试启用包内虚拟滚动支持
检查该包的版本更新或配置参数,部分多选组件包会提供虚拟滚动(Virtual Scroll)的开关选项(例如useVirtualScroll)。如果存在相关配置,直接开启即可实现只渲染可见区域的列表项,大幅降低渲染压力。
2. 自定义弹窗+虚拟列表实现
如果包本身不支持虚拟滚动,直接替换默认弹窗为自定义实现,用ListView.builder实现按需渲染:
第一步:替换原多选字段为自定义触发组件
InkWell( onTap: () => _showCustomMultiselectDialog(context), child: Container( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: Row( children: [ if (selectedPropertyList.isEmpty) Text('Please Select a value', style: TextStyle(color: Colors.grey)), if (selectedPropertyList.isNotEmpty) Wrap( spacing: 8, children: selectedPropertyList.map((item) { return Chip( label: Text(item), shape: RoundedRectangleBorder( side: BorderSide(color: Colors.red, width: 1), borderRadius: BorderRadius.circular(16), ), onDeleted: () { setState(() { selectedPropertyList.remove(item); }); }, ); }).toList(), ), Spacer(), Icon(Icons.arrow_drop_down), ], ), ), )
第二步:实现带虚拟滚动的自定义弹窗
void _showCustomMultiselectDialog(BuildContext context) { List<String> tempSelected = List.from(selectedPropertyList); // 提前解析并缓存数据,避免重复创建实例与Map解析 final propertyList = PropertyListAndPhase().propertyList.map((e) => e['key']!).toList(); showDialog( context: context, builder: (ctx) { return AlertDialog( title: Text('Units', style: TextStyle(color: Colors.red)), content: SizedBox( width: double.maxFinite, height: MediaQuery.of(context).size.height * 0.6, // ListView.builder仅渲染当前可见区域的列表项 child: ListView.builder( itemCount: propertyList.length, itemBuilder: (_, index) { final item = propertyList[index]; return CheckboxListTile( value: tempSelected.contains(item), title: Text(item), onChanged: (val) { setState(() { if (val == true) { tempSelected.add(item); } else { tempSelected.remove(item); } }); }, ); }, ), ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: Text('Cancel'), ), TextButton( onPressed: () { setState(() { selectedPropertyList = tempSelected; }); Navigator.pop(ctx); }, child: Text('Save'), ), ], ); }, ); }
3. 额外性能优化
- 优化数据结构:将原
List<Map<String, String>>改为List<String>,减少Map解析开销:class PropertyListAndPhase { List<String> propertyList = [ 'E1', 'E1`', // ...其他616项 ]; } - 缓存数据实例:在
initState中提前初始化数据,避免每次弹窗都创建新实例:late List<String> _cachedPropertyList; @override void initState() { super.initState(); _cachedPropertyList = PropertyListAndPhase().propertyList; }
内容的提问来源于stack exchange,提问作者Mahmoud
相关产品推荐
相关产品推荐

