如何从列表生成DropdownMenuItem并解决DropdownButton重复值报错问题
错误原因
你代码的核心问题是把dropdownItems定义为了类成员/全局变量,每次调用getDropDownItems()方法时,都会往已有的列表里重复追加一轮DropdownMenuItem元素:
- 首次页面渲染调用
getDropDownItems(),列表里会生成21个对应货币的选项 - 每次触发
setState更新选中值后,组件重绘会再次调用getDropDownItems(),又会往原有列表里追加21个重复的选项,导致出现多个value为USD(以及其他重复货币值)的选项,触发重复值报错。
修复方案
有两种常用修复方式,任选其一即可:
方案1:每次调用方法时初始化空列表
把dropdownItems的声明移到getDropDownItems方法内部,每次调用都生成全新的列表,避免重复追加:
List<DropdownMenuItem<String>> getDropDownItems() { // 每次调用都创建新的空列表 List<DropdownMenuItem<String>> dropdownItems = []; for (String currency in currenciesList) { var newItem = DropdownMenuItem( child: Text(currency), value: currency, ); dropdownItems.add(newItem); } return dropdownItems; }
方案2:提前初始化一次选项列表
如果选项不会动态变化,直接在初始化阶段生成一次列表即可,不需要每次重绘都重新生成:
- 删掉
getDropDownItems方法,在initState里一次性生成选项:
late String selectedCurrency; late List<DropdownMenuItem<String>> dropdownItems; @override void initState() { super.initState(); selectedCurrency = 'USD'; dropdownItems = currenciesList.map((currency) => DropdownMenuItem( child: Text(currency), value: currency, )).toList(); }
- DropdownButton直接传入提前生成的列表:
child: DropdownButton<String>( value: selectedCurrency, // 直接传预生成的列表,不用每次调用方法生成 items: dropdownItems, onChanged: (value) { setState(() { selectedCurrency = value!; }); }, )
内容的提问来源于stack exchange,提问作者Jimmyjbk
相关产品推荐
相关产品推荐

