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

Flutter中在DropdownButton使用JSON列表遇空指针红屏问题求助

问题解决思路

核心问题分析

  1. jsonList作用域错误:你在readJson方法里定义的jsonList是局部变量,无法被customJsonDropDown方法访问,导致DropdownButton尝试调用null.map()触发空指针。
  2. 未初始化成员变量:即使把jsonList改为类成员,若未初始化为空列表,在JSON加载完成前它会是null,可能引发潜在错误。
  3. Dropdown初始值不匹配:如果初始value和jsonList中的选项不匹配,也会导致Dropdown报错。

修正步骤

1. 定义类成员变量

在你的State类中声明jsonList并初始化为空列表:

List jsonList = [];

2. 修改readJson方法

把局部变量改为给成员变量赋值,同时移除json.decode前多余的await(它是同步方法):

Future<void> readJson() async {
  final response = await rootBundle.loadString('assets/json/units.json');
  final data = json.decode(response);

  setState(() {
    jsonList = data["length"] as List;
    print(jsonList);
  });
}

3. 处理Dropdown初始值

在State类中添加选中值变量,并在JSON加载完成后初始化:

String? selectedValue;

// 在readJson的setState中补充:
selectedValue = jsonList.first['conversion'].toString();

4. 调整customJsonDropDown方法

添加加载状态判断,确保JSON未加载完成时显示占位符:

Widget customJsonDropDown(String? value, void Function(String?) onChange) {
  if (jsonList.isEmpty) {
    return Container(
      height: 50,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(9),
        color: Colors.white,
      ),
      child: const Center(child: Text("加载中...")),
    );
  }

  return Container(
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(9),
      color: Colors.white,
    ),
    child: Padding(
      padding: const EdgeInsets.only(left: 10, right: 5),
      child: SizedBox(
        height: 50,
        child: DropdownButton<String>(
          value: value,
          onChanged: onChange,
          items: jsonList.map((item) {
            return DropdownMenuItem(
              child: Text(item['name']),
              value: item['conversion'].toString(),
            );
          }).toList(),
          underline: Container(),
          isExpanded: true,
        ),
      ),
    ),
  );
}

5. 初始化时加载JSON

在State的initState中调用readJson,确保页面启动时加载数据:

@override
void initState() {
  super.initState();
  readJson();
}

额外优化建议

创建数据模型类解析JSON,避免直接使用Map,提升代码可读性和类型安全性:

class Unit {
  final String name;
  final double conversion;
  final bool isBaseUnit;

  Unit({required this.name, required this.conversion, this.isBaseUnit = false});

  factory Unit.fromJson(Map<String, dynamic> json) {
    return Unit(
      name: json['name'],
      conversion: json['conversion'],
      isBaseUnit: json['base_unit'] ?? false,
    );
  }
}

修改readJson的解析逻辑:

setState(() {
  jsonList = (data["length"] as List).map((item) => Unit.fromJson(item)).toList();
  selectedValue = (jsonList.first as Unit).conversion.toString();
});

对应的DropdownMenuItem调整为:

items: (jsonList as List<Unit>).map((unit) {
  return DropdownMenuItem(
    child: Text(unit.name),
    value: unit.conversion.toString(),
  );
}).toList(),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:15:59