Flutter依赖下拉菜单问题:FormHelper与id/name无法实现联动
解决Flutter国家-城市依赖下拉菜单联动问题
问题核心
- 国家下拉框未明确指定
optionValue和optionLabel,组件无法识别数据字段 - 过滤城市时直接覆盖原始列表,导致后续无法重新筛选
- 联动操作后未触发UI更新,城市下拉框不会自动刷新
- 数据字段大小写不匹配:国家用小写
id/name,城市用大写ID/Name/ParentId
修复方案及完整代码
1. 拆分城市列表:保留原始数据,用过滤列表渲染下拉框
class _HomePageState extends State<HomePage> { List<dynamic> countries = []; List<dynamic> originalCities = []; // 存储所有城市原始数据 List<dynamic> filteredCities = []; // 存储当前过滤后的城市数据 String? countryId; String? cityId;
2. 初始化数据时填充原始城市列表
@override void initState() { super.initState(); // 初始化国家数据 countries.add({"id": 1, "name": "Belgien"}); countries.add({"id": 2, "name": "Deutschland"}); // 初始化原始城市数据 originalCities = [ {"ID": 1, "Name": "Nivelles", "ParentId": 1}, {"ID": 1, "Name": "Augsburg", "ParentId": 2}, {"ID": 2, "Name": "Berlin", "ParentId": 2}, ]; }
3. 配置下拉框字段并实现联动逻辑
@override Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( title: const Text("Flutter - Dependent Dropdown"), backgroundColor: const Color(0xFF2F562E), centerTitle: true, ), body: Container( color: const Color(0x406E6C6C), child: Column( children: [ // 国家下拉框 FormHelper.dropDownWidgetWithLabel( context, "Land", "Selected Country", countryId, countries, (onChangedVal) { setState(() { countryId = onChangedVal.toString(); // 根据选中国家ID过滤城市 filteredCities = originalCities.where((city) => city["ParentId"].toString() == countryId ).toList(); // 重置城市选中状态 cityId = null; }); print("Selected Country: $onChangedVal"); }, (onValidateVal) { if (onValidateVal == null) { return 'Please Select Country'; } return null; }, borderColor: Theme.of(context).primaryColor, borderFocusColor: Theme.of(context).primaryColor, borderRadius: 10, optionValue: "id", // 匹配国家数据的小写id字段 optionLabel: "name", // 匹配国家数据的小写name字段 ), // 城市下拉框 FormHelper.dropDownWidgetWithLabel( context, "Stadt", "Select City", cityId, filteredCities, (onChangedVal) { setState(() { cityId = onChangedVal.toString(); }); print("Selected City: $onChangedVal"); }, (onValidate) => null, borderColor: Theme.of(context).primaryColor, borderFocusColor: Theme.of(context).primaryColor, borderRadius: 10, optionValue: "ID", // 匹配城市数据的大写ID字段 optionLabel: "Name", // 匹配城市数据的大写Name字段 ), ], ), ), ), ); }
关键修复说明
- 字段匹配:严格按照数据字段的大小写设置
optionValue和optionLabel,避免组件找不到对应字段报错 - 数据隔离:用
originalCities保存全部城市数据,每次过滤都基于原始数据,防止数据丢失 - 状态更新:所有值变更和列表过滤操作都包裹在
setState()中,确保UI实时刷新 - 类型统一:将选中ID转为字符串,避免数字与字符串比较时的类型不匹配问题
内容的提问来源于stack exchange,提问作者ebprognx
相关产品推荐
相关产品推荐

