Flutter中ListView.builder如何获取Map字面量键值渲染列表项
解答
Dart的Map类型不支持直接通过数字索引访问键或值。
Dart默认的Map实现为LinkedHashMap,会严格保留键值对的插入顺序,你只需要把Map的键或键值对转换为支持索引访问的列表,就能配合ListView.builder返回的index参数拿到对应项的内容。
具体实现
两种常用写法,数据量大时推荐第二种,性能更好:
写法1:实时获取对应索引的键
无需额外定义变量,直接在itemBuilder回调中取对应内容即可:
itemBuilder: (context,index) { // 获取当前索引对应的图标名称(Map的key) String iconName = icons.keys.elementAt(index); // 通过key获取对应的IconData IconData iconData = icons[iconName]!; return Padding( padding: EdgeInsets.symmetric(vertical: 10.0), child: ListTile( onTap: (){}, leading: CircleAvatar( backgroundColor: Colors.blue, child: Icon(iconData), ), title: Text(iconName, style: TextStyle(fontSize: 30.0, color: Colors.blue),), ), ); }
注意:icons.keys返回的是可迭代对象,elementAt方法每次调用都会从头遍历到目标索引位置,数据量较大时会有额外性能开销。
写法2:提前转成键值对列表(推荐)
提前把Map的键值对转换为List,后续通过索引访问的时间复杂度为O(1),性能更稳定:
- 在State类中提前生成键值对列表:
class _HomeScreenState extends State<HomeScreen> { Map<String, IconData> icons = { 'ac_unit': Icons.ac_unit, 'ac_unit_sharp': Icons.ac_unit_sharp, 'ac_unit_rounded': Icons.ac_unit_rounded, 'ac_unit_outlined': Icons.ac_unit_outlined, 'access_alarm': Icons.access_alarm }; // 初始化时转换为固定顺序的键值对列表 late final List<MapEntry<String, IconData>> iconEntries = icons.entries.toList(); // 其余build逻辑保持不变
- 在
itemBuilder中直接通过索引取值:
itemBuilder: (context,index) { final currentItem = iconEntries[index]; return Padding( padding: EdgeInsets.symmetric(vertical: 10.0), child: ListTile( onTap: (){}, leading: CircleAvatar( backgroundColor: Colors.blue, child: Icon(currentItem.value), ), title: Text(currentItem.key, style: TextStyle(fontSize: 30.0, color: Colors.blue),), ), ); }
如果你的图标列表只有几十上百项,两种写法没有明显体验差异;如果列表项超过千条,优先选择第二种写法。
内容的提问来源于stack exchange,提问作者Irfan Ganatra
相关产品推荐
相关产品推荐

