Flutter二级联动DropdownButtonForm切换城市报错求助
解决Flutter城市区县联动Dropdown切换时的断言错误
问题核心:切换城市后,原选中的区县值不在新加载的区县列表中,违反了DropdownButtonFormField的断言规则——选中值必须存在于选项列表中且唯一。
具体解决方案
1. 切换城市时直接重置区县选中值
在城市选择的onChanged回调里,更新城市状态的同时,把区县选中值重置为null,确保后续区县Dropdown的value始终在新选项列表范围内。
示例代码:
DropdownButtonFormField<String>( value: selectedCity, items: cities.map((city) => DropdownMenuItem(value: city, child: Text(city))).toList(), onChanged: (newCity) { setState(() { selectedCity = newCity; // 重置区县选中值 selectedDistrict = null; // 加载当前城市对应的区县列表 districts = getDistrictsByCity(newCity); }); }, )
2. 按需校验区县选中值(可选)
如果希望保留"新城市恰好包含旧区县则不重置"的逻辑,可以在加载新区县列表后,检查原选中值是否存在,不存在再重置:
void _onCityChanged(String? newCity) { if (newCity == null) return; setState(() { selectedCity = newCity; final newDistricts = getDistrictsByCity(newCity); districts = newDistricts; // 旧区县不在新列表里就重置 if (!newDistricts.contains(selectedDistrict)) { selectedDistrict = null; } }); }
3. 给区县Dropdown加默认占位选项
为区县Dropdown添加值为null的默认选项(比如"请选择区县"),确保重置后有对应的选项匹配,避免空列表或无匹配值的情况:
DropdownButtonFormField<String>( value: selectedDistrict, hint: const Text('请选择区县'), items: [ // 默认占位选项 const DropdownMenuItem(value: null, child: Text('请选择区县')), ...districts.map((district) => DropdownMenuItem(value: district, child: Text(district))).toList(), ], onChanged: (newDistrict) { setState(() { selectedDistrict = newDistrict; }); }, )
4. 自定义区县对象的匹配逻辑(如果用对象而非字符串)
如果区县是自定义类(比如District),必须重写==运算符和hashCode,确保Dropdown能正确判断值是否匹配:
class District { final String id; final String name; District({required this.id, required this.name}); @override bool operator ==(Object other) => identical(this, other) || other is District && runtimeType == other.runtimeType && id == other.id; @override int get hashCode => id.hashCode; }
核心原则
始终保证DropdownButtonFormField的value属性值存在于当前的items列表中,切换城市时必须同步更新区县的选中状态,避免出现"值不在选项里"的情况。
内容的提问来源于stack exchange,提问作者Emir Bolat
相关产品推荐
相关产品推荐

