Flutter/Dart:如何从snapshot.data[index]创建Map并提取id值
问题说明
我尝试访问并使用snapshot.data[index]中的值,目前打印snapshot.data[index]的结果如下:
I/flutter (11316): Code : LE-0000000002 I/flutter (11316): Description : test_01 I/flutter (11316): Organisation Unit : 01_01_04_01_SA - Shah Alam I/flutter (11316): Date Reported : 18/09/2020 I/flutter (11316): Status : LE110 - Pending Approval I/flutter (11316): RunHyperlink : {classid: 25510, id: 2, mad_key: 32835}
以下是向snapshot提供数据的代码:
List<Map<String, dynamic>> incidentList = [ for (final json in listNode.map((x) => x.toJson())) { 'Code': json['field'][0]['field_value'], 'Description': json['field'][1]['field_value'], 'Organisation Unit': json['field'][2]['field_value'], 'Date Reported': json['field'][3]['field_value'], 'Status': json['field'][4]['field_value'], 'RunHyperlink' : json['run_hyperlink'] } ]; final List<String> values = []; for(final item in incidentList){ String groupedElement = ""; for(var innerItem in item.entries) { groupedElement += "${innerItem.key} : ${innerItem.value}\n"; } values.add(groupedElement); } await WriteCache.setListString(key: 'cache4', value: values);
FutureBuilder代码如下:
FutureBuilder( future: ReadCache.getStringList(key: 'cache4'), builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), child: ListTile( onTap: () { print(snapshot.data[index]); }, title: Padding( padding: const EdgeInsets.only(top: 10), child: Text(snapshot.data[index], style: GoogleFonts.poppins( textStyle: const TextStyle( fontWeight: FontWeight.normal, fontSize: 20, ), )), ), tileColor: Colors.blueGrey[200], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), ); }); } else { return const Text("No Data"); } }, ),
我需要获取并使用输出中的id值,知道要创建Map来实现,但不清楚具体方法。请帮忙处理,以便将id值作为查询参数传递。
解决方案
你当前的核心问题是把结构化的incidentList(Map列表)转成了纯字符串存储,导致后续无法直接提取嵌套的id值。正确的做法是保留数据的Map结构,通过JSON序列化缓存,再反序列化读取。
步骤1:修改缓存存储逻辑
不要将Map转成字符串列表,而是直接把incidentList序列化为JSON字符串缓存:
// 导入dart:convert包 import 'dart:convert'; // 将incidentList转为JSON字符串 String incidentJson = jsonEncode(incidentList); await WriteCache.setString(key: 'cache4', value: incidentJson);
步骤2:修改FutureBuilder读取逻辑
读取缓存后,将JSON字符串反序列化为List<Map<String, dynamic>>,就能直接访问所有字段:
FutureBuilder( future: ReadCache.getString(key: 'cache4'), builder: (context, snapshot) { if (snapshot.hasData && snapshot.data!.isNotEmpty) { // 反序列化回原Map列表结构 List<Map<String, dynamic>> incidentList = jsonDecode(snapshot.data!) as List<Map<String, dynamic>>; return ListView.builder( itemCount: incidentList.length, itemBuilder: (context, index) { // 获取当前条目数据 Map<String, dynamic> currentItem = incidentList[index]; // 直接提取RunHyperlink中的id int? targetId = currentItem['RunHyperlink']?['id']; return Padding( padding: const EdgeInsets.all(8.0), child: ListTile( onTap: () { // 这里可直接使用targetId作为查询参数 print("待传递的ID:$targetId"); // 示例:跳转到详情页并携带参数 // Navigator.push(context, MaterialPageRoute(builder: (_) => DetailPage(id: targetId))); }, title: Padding( padding: const EdgeInsets.only(top: 10), child: Text( // 拼接成原有的显示格式 "Code : ${currentItem['Code']}\n" "Description : ${currentItem['Description']}\n" "Organisation Unit : ${currentItem['Organisation Unit']}\n" "Date Reported : ${currentItem['Date Reported']}\n" "Status : ${currentItem['Status']}\n" "RunHyperlink : ${currentItem['RunHyperlink']}", style: GoogleFonts.poppins( textStyle: const TextStyle( fontWeight: FontWeight.normal, fontSize: 20, ), ), ), ), tileColor: Colors.blueGrey[200], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), ); }); } else { return const Text("No Data"); } }, ),
方案优势
- 避免了字符串解析的复杂操作和出错风险
- 保留了完整的结构化数据,后续扩展其他字段(如classid、mad_key)也无需额外修改
- 直接通过Map键值对访问数据,代码更简洁易维护
内容的提问来源于stack exchange,提问作者JoshuaaMarkk
相关产品推荐
相关产品推荐

