Flutter二级联动下拉菜单实现及空安全错误排查求助
问题分析与修复方案
错误原因
- 第二个下拉框选项生成逻辑错误:原代码通过
where筛选州后,直接map提取城市列表,导致后续将整个城市列表作为单个选项,而非遍历每个城市生成独立选项; - 初始状态空值未处理:页面初始化时
_originState为null,第二个下拉框无有效选项,触发内部空值检查异常; - 冗余类型转换:第一个下拉框的
onChanged中,value as String?属于多余操作,value本身就是可空字符串类型。
修复后完整代码
// 状态变量定义 String? _originState; String? _originCity; // 第一个州选择下拉框 DropdownButtonFormField<String?>( decoration: const InputDecoration( labelText: "Origin - State", border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(8.0), ), ), ), style: const TextStyle( fontSize: 17, color: Colors.black, ), value: _originState, // 绑定选中值,保持状态同步 onChanged: (value) { setState(() { _originState = value; _originCity = null; // 切换州时重置城市选中值,避免无效选项 }); }, items: cityMap.map((val) { return DropdownMenuItem<String>( value: val["state"], child: Text(val["state"] ?? ""), // 防御性处理,避免state为空时崩溃 ); }).toList(), ), const SizedBox(height: 15), // 第二个城市选择下拉框 DropdownButtonFormField<String?>( decoration: const InputDecoration( labelText: "Origin - City", border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(8.0), ), ), ), style: const TextStyle( fontSize: 17, color: Colors.black, ), value: _originCity, // 未选择州时禁用下拉框 onChanged: _originState == null ? null : (value) { setState(() { _originCity = value; }); }, // 动态生成城市选项 items: () { if (_originState == null) { // 未选州时返回提示选项 return [ const DropdownMenuItem<String>( value: null, child: Text("请先选择州"), ) ]; } // 找到当前选中州对应的城市列表 final stateData = cityMap.firstWhere( (element) => element["state"] == _originState, orElse: () => {}, ); final List<String> cities = stateData["city"] ?? []; // 遍历城市生成独立选项 return cities.map((city) { return DropdownMenuItem<String>( value: city, child: Text(city), ); }).toList(); }(), ),
关键修复点说明
- 给第一个下拉框添加
value: _originState,保证选中状态与变量同步; - 切换州时重置
_originCity,避免选中的城市不属于新选中的州; - 第二个下拉框根据
_originState是否为空,动态禁用/启用,并生成对应选项; - 重构城市选项生成逻辑:先定位目标州的城市列表,再遍历每个城市生成独立选项;
- 增加空值防御处理,避免异常数据导致崩溃。
内容的提问来源于stack exchange,提问作者trng
相关产品推荐
相关产品推荐

