You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,
      };
}

关键修改点说明

  1. 接口请求优化:

    • 把loading状态的设置放到try/finally里,确保无论请求成功还是失败都会关闭加载状态
    • 添加了对接口返回数据的判断,初始化默认选中第一个选项(可选)
    • 修复了http.post的参数,适配Flutter新版本要求的Uri.parse(url)
  2. Dropdown逻辑修正:

    • 遍历的是payloadListdropdown[0].rows,也就是接口返回的服务列表数组
    • DropdownMenuItem的child使用当前遍历的row.sName,动态展示每个服务名称
    • value使用row.ServicesId,保证每个选项的唯一性,方便后续获取选中的服务ID
    • 添加了加载状态和空数据的UI提示,避免空指针异常
  3. LeadService类更新:

    • 新增了refcode和trows字段,和你提供的JSON结构保持一致,避免解析时丢失数据

这样修改后,你的Dropdown就能正确展示JSON里的所有rows数据啦!

内容的提问来源于stack exchange,提问作者Manali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:50