Flutter DropdownButton报错:值1对应项数量不符问题求助
问题分析与解决方案
错误原因
这个断言错误的核心是城市DropdownButton的当前值_city不在新加载的城市列表选项中,或者列表中存在多个与_city值相同的选项。具体来说:
- 你初始化
_city = '1',但切换州/省后,新获取的城市列表里大概率没有ID为1的城市; - 切换州时没有重置
_city的值,导致旧值与新列表不匹配,违反了DropdownButton的规则:value必须是items中的某一项,且唯一存在。
修复步骤
- 修改
_city的类型与初始值:将其改为可空类型,初始值设为null,避免初始时城市列表为空但value不为空的矛盾。 - 切换州时重置城市选中值:在选择新的州/省后,立即将
_city重置为null,或者默认选中新城市列表的第一个元素。 - 同步DropdownButton的类型:城市DropdownButton的泛型要改为可空类型,匹配
_city的类型。
修改后的完整代码
import 'dart:convert'; import 'package:hr_jobform/customColors.dart'; import 'package:http/http.dart' as http; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class CitiesStateDropdownButton extends StatefulWidget { const CitiesStateDropdownButton({super.key}); @override State<CitiesStateDropdownButton> createState() => CitiesStateDropdownButtonState(); } class CitiesStateDropdownButtonState extends State<CitiesStateDropdownButton> { @override void initState() { _getStatesList(); super.initState(); } @override Widget build(BuildContext context) { return Wrap(children: <Widget>[ Padding( padding: const EdgeInsets.fromLTRB(8, 15, 8, 8), child: ConstrainedBox( constraints: BoxConstraints.tight(const Size(219, 50)), child: DropdownButton<String>( value: _state, iconSize: 30, icon: null, style: TextStyle( color: Palette.customColors, fontSize: 16, ), hint: const Text('Select State'), onChanged: (String? newValue) { setState(() { _state = newValue!; _city = null; // 重置城市选中值,避免与新列表不匹配 _getCitiesList(); print(_state); }); }, items: states.map((item) { return DropdownMenuItem( child: Text(item['name']), value: item['id'].toString(), ); }).toList() ?? [], ), ), ), //======================================================== City Wrap( children: <Widget>[ Padding( padding: const EdgeInsets.fromLTRB(8, 15, 8, 8), child: ConstrainedBox( constraints: BoxConstraints.tight(const Size(187, 50)), child: DropdownButton<String?>( // 改为可空泛型 value: _city, iconSize: 30, icon: null, style: TextStyle( color: Palette.customColors, fontSize: 16, ), hint: const Text('Select City'), onChanged: (String? newValue) { setState(() { _city = newValue; print(_city); }); }, items: cities.map((item) { return DropdownMenuItem( child: Text(item['name']), value: item['id'].toString(), ); }).toList() ?? [], ), ), ), ], ), ]); } //=============================================================================== Api Calling here //CALLING State API HERE // Get Departamento information by API late List states = []; late String _state = '1'; String statesUrl = "http://localhost:3000/states/getAllStates"; _getStatesList() async { try { http.Response response = await http.get(Uri.parse(statesUrl)); if (response.statusCode == 200) { print(response.body); var data = jsonDecode(response.body); setState(() { states = data['state']; }); return jsonDecode(response.body); } else { return ("Server Error"); } } catch (e) { return print(e); } } // Get Cities information by API late List cities = []; late String? _city = null; // 改为可空类型,初始值null _getCitiesList() async { try { http.Response response = await http.get(Uri.parse("http://localhost:3000/cities/getAllCities?id=$_state")); if (response.statusCode == 200) { print(response.body); var data = jsonDecode(response.body); setState(() { cities = data['City']; // 可选:默认选中第一个城市(如果需要) if (cities.isNotEmpty) { _city = cities[0]['id'].toString(); } else { _city = null; } print(cities); }); return jsonDecode(response.body); } else { return ("Server Error"); } } catch (e) { return print(e); } } }
额外检查
如果修复后仍报错,需要确认:
- 城市API返回的列表中是否存在重复的
id值,如果有,需要确保每个城市的id唯一; - 州/省的初始值
_state = '1'是否在加载的州列表中,避免初始时州DropdownButton也出现同样问题。
内容的提问来源于stack exchange,提问作者Eder Savillon
相关产品推荐
相关产品推荐

