Flutter中如何在Dropdown组件中展示JSON嵌套数组?
解决Dropdown展示JSON中rows数据的问题
我看了你这段Flutter代码,发现几个关键问题导致你没法正确把JSON里的rows数据展示在Dropdown组件里,下面是修正方案和解释:
问题分析
- 你的
payloadListdropdown是List<LeadService>类型,而接口返回的JSON是包含单个LeadService对象的数组,所以你需要取payloadListdropdown[0].rows才是要展示的服务列表,而不是直接遍历payloadListdropdown - DropdownMenuItem里硬编码了
payloadListdropdown[0].rows[1].sName,这会导致所有选项都是同一个固定值,没有遍历每一行数据 value: item[1].toString()是错误的,因为item是Rows对象,不是数组,应该用Rows里的唯一标识(比如ServicesId)- 没有处理加载状态和空数据的情况,容易出现空指针异常
修改后的完整代码
class _MyAppState extends State<MyAppdrop> { List<LeadService> payloadListdropdown; bool loading = false; String _mySelection; List<LeadService> payloadFromJson(String str) => List<LeadService>.from( json.decode(str).map((x) => LeadService.fromJson(x))); String payloadToJson(List<LeadService> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson()))); Future<List<LeadService>> requestMethodspinner() async { var url = ""; // 这里替换成你的实际接口地址 Map<String, String> headers = { 'Content-type': 'application/json', 'Accept': 'application/json', }; try { setState(() { loading = true; }); final response = await http.post(Uri.parse(url), headers: headers); print(response.body); print(response.statusCode); if (response.statusCode == 200) { payloadListdropdown = payloadFromJson(response.body); // 初始化默认选中第一个选项(可选) if (payloadListdropdown.isNotEmpty && payloadListdropdown[0].rows.isNotEmpty) { setState(() { _mySelection = payloadListdropdown[0].rows[0].ServicesId; }); } } else { throw Exception('Failed to load data'); } } catch (e) { print(e.toString()); // 这里可以添加错误提示逻辑 } finally { setState(() { loading = false; }); } return payloadListdropdown; } @override void initState() { super.initState(); requestMethodspinner(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("DropDown"), ), body: Center( child: loading ? const CircularProgressIndicator() // 加载中提示 : (payloadListdropdown == null || payloadListdropdown.isEmpty || payloadListdropdown[0].rows.isEmpty) ? const Text("暂无数据") // 空数据提示 : DropdownButton<String>( items: payloadListdropdown[0].rows.map((row) { return DropdownMenuItem<String>( child: Text(row.sName), // 展示当前行的服务名称 value: row.ServicesId, // 用ServicesId作为选项的唯一值 ); }).toList(), onChanged: (newVal) { setState(() { _mySelection = newVal; }); }, value: _mySelection, hint: const Text("请选择服务"), // 未选中时的提示 ), ), ); } } // LeadService和Rows类保持结构匹配JSON class LeadService { int status; String msg; List<Rows> rows; String sql; dynamic reserved; int refcode; int trows; LeadService({ this.status, this.msg, this.rows, this.sql, this.reserved, this.refcode, this.trows, }); factory LeadService.fromJson(Map<String, dynamic> json) => LeadService( status: json["status"], msg: json["msg"], rows: List<Rows>.from(json["rows"].map((x) => Rows.fromJson(x))), sql: json["sql"], reserved: json["reserved"], refcode: json["refcode"], trows: json["trows"], ); Map<String, dynamic> toJson() => { "status": status, "msg": msg, "rows": List<dynamic>.from(rows.map((x) => x.toJson())), "sql": sql, "reserved": reserved, "refcode": refcode, "trows": trows, }; } class Rows { String ServicesId; String sName; String sCode; Rows({ this.ServicesId, this.sName, this.sCode, }); factory Rows.fromJson(Map<String, dynamic> json) => Rows( ServicesId: json["ServicesId"], sName: json["sName"], sCode: json["sCode"], ); Map<String, dynamic> toJson() => { "ServicesId": ServicesId, "sName": sName, "sCode": sCode, }; }
关键修改点说明
接口请求优化:
- 把loading状态的设置放到try/finally里,确保无论请求成功还是失败都会关闭加载状态
- 添加了对接口返回数据的判断,初始化默认选中第一个选项(可选)
- 修复了
http.post的参数,适配Flutter新版本要求的Uri.parse(url)
Dropdown逻辑修正:
- 遍历的是
payloadListdropdown[0].rows,也就是接口返回的服务列表数组 - DropdownMenuItem的
child使用当前遍历的row.sName,动态展示每个服务名称 value使用row.ServicesId,保证每个选项的唯一性,方便后续获取选中的服务ID- 添加了加载状态和空数据的UI提示,避免空指针异常
- 遍历的是
LeadService类更新:
- 新增了
refcode和trows字段,和你提供的JSON结构保持一致,避免解析时丢失数据
- 新增了
这样修改后,你的Dropdown就能正确展示JSON里的所有rows数据啦!
内容的提问来源于stack exchange,提问作者Manali
相关产品推荐
相关产品推荐

