Flutter/Dart:如何将LinkedMap<dynamic,dynamic>渲染到ListView.builder
实现步骤
1. 提取所有metadata数据
先从转换后的LinkedMap里逐层遍历,把符合要求的metadata提取到统一列表中,方便后续ListView调用:
List<Map<String, dynamic>> promoMetadataList = []; // 第一层:遍历所有Product(注意替换实际数据中的产品列表key,比如你的API返回可能用'products'或其他字段) final products = data['products'] as List<dynamic>?; if (products != null) { for (var product in products) { // 第二层:获取当前Product的Promos列表 final promos = product['Promos'] as List<dynamic>?; if (promos != null) { for (var promo in promos) { // 第三层:获取Price对象的metadata(若API结构中Promos下的Price有嵌套,比如promo['Prices'],请对应调整路径) final priceMetadata = promo['metadata'] as Map<String, dynamic>?; // 判空避免崩溃,确保字段存在再加入列表 if (priceMetadata != null && priceMetadata.containsKey('dateStart') && priceMetadata.containsKey('dateEnd') && priceMetadata.containsKey('promoName')) { promoMetadataList.add(priceMetadata); } } } } }
2. 用ListView.builder展示数据
基于整理好的promoMetadataList,直接通过ListView.builder渲染每个促销信息:
ListView.builder( itemCount: promoMetadataList.length, itemBuilder: (context, index) { final metadata = promoMetadataList[index]; return ListTile( title: Text(metadata['promoName'] ?? '无促销名称'), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('开始时间: ${metadata['dateStart'] ?? '未知'}'), Text('结束时间: ${metadata['dateEnd'] ?? '未知'}'), ], ), ); }, )
可选:封装实体类(类型安全写法)
如果项目规模较大,建议把Metadata封装成实体类,避免动态类型的潜在问题:
// 定义Metadata实体类 class PromoMetadata { final String dateStart; final String dateEnd; final String promoName; PromoMetadata({ required this.dateStart, required this.dateEnd, required this.promoName, }); // 从Map转换为实体对象 factory PromoMetadata.fromMap(Map<String, dynamic> map) { return PromoMetadata( dateStart: map['dateStart'] ?? '', dateEnd: map['dateEnd'] ?? '', promoName: map['promoName'] ?? '', ); } } // 提取数据时转换为实体列表 List<PromoMetadata> promoMetadataList = []; // ...(保留前面的遍历逻辑) // 替换添加逻辑: promoMetadataList.add(PromoMetadata.fromMap(priceMetadata)); // ListView.builder调用实体类字段: itemBuilder: (context, index) { final metadata = promoMetadataList[index]; return ListTile( title: Text(metadata.promoName), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('开始时间: ${metadata.dateStart}'), Text('结束时间: ${metadata.dateEnd}'), ], ), ); }
内容的提问来源于stack exchange,提问作者user3352042
相关产品推荐
相关产品推荐

