Flutter中如何在FutureBuilder的ListView内仅获取Map的value值展示
Flutter FutureBuilder遍历Map获取value值解决方案
现有JSON数据
{ "0": "traceroute to www.google.com ( 142.250.180.36 ), 30 hops max", "1": "Hop Address Host Name Time ", "2": "1 0.0.0.0 _gateway 3.03ms ", "3": "2 0.0.0.0 0.0.0.0 5.28ms ", "4": "3 0.0.0.0 0.0.0.0 7.63ms ", "5": "4 0.0.0.0 00.0.0.0 9.65ms ", "6": "5 172.19.14.121 172.19.14.121 10.55ms ", "7": "6 58.181.114.10 58.181.114.10 29.9ms ", "8": "7 10.253.4.74 10.253.4.74 31.0ms ", "9": "8 10.253.4.26 10.253.4.26 148.22ms ", "10": "9 74.125.146.188 74.125.146.188 43.09ms ", "11": "10 ******************** ********************************************* 5179.56ms ", "12": "11 142.251.51.56 142.251.51.56 45.78ms ", "13": "12 108.170.247.23 108.170.247.23 43.23ms ", "14": "13 209.85.240.55 209.85.240.55 48.81ms ", "15": "14 209.85.241.249 209.85.241.249 42.3ms ", "16": "15 ***************** ***************************************** 5024.85ms ", "17": "16 142.250.180.36 mct01s14-in-f4.1e100.net 44.03ms ", "18": "Reached destination" }
现有代码
UI层代码
Container( child: FutureBuilder<Map<String, dynamic>>( future: fetchData(), builder: (context, snapshot) { if (snapshot.hasData) { return Expanded( child: ListView.builder( physics: AlwaysScrollableScrollPhysics(), shrinkWrap: false, itemCount: snapshot.data!.length, itemBuilder: (BuildContext context, int index) { return Container( height: 50, color: Colors.white, child: Center( child: Text(snapshot.data!.entries .elementAt(index) .toString()), ), ); }), ); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } // 默认显示加载动画 return CircularProgressIndicator(); }, ), ),
接口请求代码
Future<Map<String, dynamic>> fetchData() async { print("Fetch data is called"); Map<String, String> header = { 'Content-type': 'application/json', 'Accept': 'application/json', "Access-Control-Allow-Headers": "Access-Control-Allow-Origin, Accept", 'Authorization': '<Your token>' }; final response = await http.get(Uri.parse('http://192.168.100.9:7001/'), headers: header); if (response.statusCode == 200) { var jsonResponse = json.decode(response.body); return jsonResponse; } else { throw Exception('Unexpected error occured!'); } }
问题说明
当前使用snapshot.data!.entries.elementAt(index).toString()会输出MapEntry(key: value)格式的内容,仅需要获取value值展示。
解决方案
MapEntry本身自带value属性,直接调用即可,你可以将Text组件的代码修改为以下两种写法:
写法1:通过entries属性直接取value
Text(snapshot.data!.entries.elementAt(index).value.toString())
写法2:通过index转换为key直接取值(适用于当前key为连续数字字符串的场景)
Text(snapshot.data![index.toString()].toString())
额外优化建议
可以先把Map的value提前转为List,减少列表滚动时的重复计算,修改后逻辑如下:
if (snapshot.hasData) { // 提前把所有value转为List,后续直接按索引取值即可 final valueList = snapshot.data!.values.toList(); return Expanded( child: ListView.builder( physics: AlwaysScrollableScrollPhysics(), shrinkWrap: false, itemCount: valueList.length, itemBuilder: (BuildContext context, int index) { return Container( height: 50, color: Colors.white, child: Center( child: Text(valueList[index].toString()), ), ); }), ); }
内容的提问来源于stack exchange,提问作者doc
相关产品推荐
相关产品推荐

