Flutter二级DropdownButton切换时出现重复值错误求助
问题分析
错误提示there should be exactly one item with dropdownbutton 's value either zero or 2 or more [DropdownMenuItem]s were detected with the same value的核心原因:
- 切换第一个下拉菜单(Gol)时,第二个下拉菜单(Vehicle)的选中值
vehicleValue未被重置,仍保留旧值。 - 新切换后的车辆列表中不存在该旧值,导致
DropdownButtonFormField无法匹配到对应的DropdownMenuItem,触发异常。 - 第二个下拉菜单未绑定
value参数,控件无法正确关联选中状态。
解决方案
1. 重置第二个下拉的选中值
在第一个下拉的onChanged回调中,更新golValue后立即将vehicleValue设为null,确保新车辆列表加载时,下拉菜单处于未选中状态。
2. 绑定第二个下拉的value参数
调用_buildDropdown时,给第二个下拉传入value: Data.vehicleValue,让控件正确关联选中值。
修改后的代码
main.dart
import 'package:flutter/material.dart'; import 'package:perhitungan_pkt_kgb/data.dart'; class HitungPkt extends StatefulWidget { const HitungPkt({super.key}); @override State<HitungPkt> createState() => _HitungPktState(); } class _HitungPktState extends State<HitungPkt> { @override Widget build(BuildContext context) { return Form( child: Column( children: [ _buildDropdown( label: 'Gol', items: Data.gol.cast<Map<String, dynamic>>(), value: Data.golValue, onChanged: (String? newValue) { setState(() { Data.golValue = newValue; Data.vehicleValue = null; // 重置第二个下拉的选中值 Data.vehicle = Data.cekgol(); }); }), if (Data.vehicle != null && Data.vehicle!.isNotEmpty) _buildDropdown( label: 'Vehicle', items: Data.vehicle!.cast<Map<String, dynamic>>(), value: Data.vehicleValue, // 绑定第二个下拉的选中值 onChanged: (String? newValue) { setState(() { Data.vehicleValue = newValue; }); }), ], ), ); } Widget _buildDropdown({ required String label, required List<Map<String, dynamic>> items, required void Function(String?) onChanged, String? value, }) { return DropdownButtonFormField<String>( decoration: InputDecoration( labelText: label, hintStyle: const TextStyle(color: Colors.blue), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Colors.blue), ), focusedBorder: OutlineInputBorder( borderSide: const BorderSide(color: Colors.blue), borderRadius: BorderRadius.circular(10), ), enabledBorder: OutlineInputBorder( borderSide: const BorderSide(color: Colors.blue), borderRadius: BorderRadius.circular(10), ), errorBorder: OutlineInputBorder( borderSide: const BorderSide(color: Colors.blue), borderRadius: BorderRadius.circular(10), ), ), value: value, items: items.map((item) { return DropdownMenuItem<String>( value: item['value'] as String, child: Text(item['label'] as String), ); }).toList(), onChanged: onChanged); } }
data.dart
class Data{ static const List gol = [ {'value': 'Car', 'label': 'Car'}, {'value': 'Bus', 'label': 'Bus'}, {'value': 'Plane', 'label': 'Plane'} ]; static String? golValue; static String? vehicleValue; static List? vehicle; static List cekgol() { if (golValue == 'Car') { return [ {'value': 'car1', 'label': 'car1'}, {'value': 'car2', 'label': 'car2'}, {'value': 'car3', 'label': 'car3'}, {'value': 'car4', 'label': 'car4'}, {'value': 'car5', 'label': 'car5'} ]; } else if (golValue == 'Bus') { return [ {'value': 'Bus1', 'label': 'Bus1'}, {'value': 'Bus2', 'label': 'Bus2'}, {'value': 'Bus3', 'label': 'Bus3'}, {'value': 'Bus4', 'label': 'Bus4'} ]; } else if (golValue == 'Plane') { return [ {'value': 'Plane1', 'label': 'Plane1'}, {'value': 'Plane2', 'label': 'Plane2'}, {'value': 'Plane3', 'label': 'Plane3'}, {'value': 'Plane4', 'label': 'Plane4'}, {'value': 'Plane5', 'label': 'Plane5'} ]; } else { return []; } } }
额外优化建议
- 尽量避免使用全局静态变量管理状态,小型项目可用
StatefulWidget成员变量替代,大型项目推荐Provider、Riverpod等状态管理方案,减少全局状态副作用。 - 对
Data.vehicle的非空判断更严谨,避免空列表时显示第二个下拉菜单。
内容的提问来源于stack exchange,提问作者Dreamer
相关产品推荐
相关产品推荐

