我试图使依赖的多级下拉列表首先包含州列表,其次包含城市列表,所有这些数据都是从API获取的。最初,我加载状态下拉列表,当我选择状态时,然后加载该状态的城市(如果我选择城市,则成功选择了城市),但是当我更改状态值时,就会发生错误。如果将在第一个下拉列表中进行更改,重新加载第二个下拉列表的正确方法是什么?
错误:应该只有一个具有[DropdownButton]值的项目:“城市”的实例。检测到零个或两个或两个以上具有相同值的[DropdownMenuItem]
Future _state; Future _city; @override void initState() { super.initState(); _state = _fetchStates(); } Future<List<StateModel>> _fetchStates() async { final String stateApi = "https://dummyurl/state.php"; var response = await http.get(stateApi); if (response.statusCode == 200) { final items = json.decode(response.body).cast<Map<String, dynamic>>(); List<StateModel> listOfUsers = items.map<StateModel>((json) { return StateModel.fromJson(json); }).toList(); return listOfUsers; } else { throw Exception('Failed to load internet'); } } Future<List<City>> _fetchCities(String id) async { final String cityApi = "https://dummyurl/city.php?stateid=$id"; var response = await http.get(cityApi); if (response.statusCode == 200) { final items = json.decode(response.body).cast<Map<String, dynamic>>(); print(items); List<City> listOfUsers = items.map<City>((json) { return City.fromJson(json); }).toList(); return listOfUsers; } else { throw Exception('Failed to load internet'); } }
状态下拉
FutureBuilder<List<StateModel>>( future: _state, builder: (BuildContext context, AsyncSnapshot<List<StateModel>> snapshot) { if (!snapshot.hasData) return CupertinoActivityIndicator(animating: true,); return DropdownButtonFormField<StateModel>( isDense: true, decoration: spinnerDecoration('Select your State'), items: snapshot.data .map((countyState) => DropdownMenuItem<StateModel>( child: Text(countyState.billstate), value: countyState, )) .toList(), onChanged:(StateModel selectedState) { setState(() { stateModel = selectedState; _city = _fetchCities(stateModel.billstateid); }); }, value: stateModel, ); }),
城市下拉
FutureBuilder<List<City>>( future: _city, builder: (BuildContext context, AsyncSnapshot<List<City>> snapshot) { if (!snapshot.hasData) return CupertinoActivityIndicator(animating: true,); return DropdownButtonFormField<City>( isDense: true, decoration: spinnerDecoration('Select your City'), items: snapshot.data .map((countyState) => DropdownMenuItem<City>( child: Text(countyState.billcity) .toList(), onChanged: (City selectedValue) { setState(() { cityModel = selectedValue; }); }, value: cityModel, ); }), class StateModel { String billstateid; String billstate; String billcountryid; StateModel({this.billstateid, this.billstate, this.billcountryid}); StateModel.fromJson(Map<String, dynamic> json) { billstateid = json['billstateid']; billstate = json['billstate']; billcountryid = json['billcountryid']; } } class City { String billcityid; String billcity; String billstateid; City({this.billcityid, this.billcity, this.billstateid}); City.fromJson(Map<String, dynamic> json) { billcityid = json['billcityid']; billcity = json['billcity']; billstateid = json['billstateid']; }
您必须cityModel = null在onChanged State下拉菜单中进行回调。
cityModel = null
onChanged
setState(() { cityModel = null; stateModel = selectedState; _city = _fetchCities(stateModel.billstateid); });
[DropdownButton]的值应恰好有一项:“城市”的实例。检测到零个或两个或两个以上具有相同值的[DropdownMenuItem]
发生此错误的原因是,value您未通过itemsof DropdownButtonFormField(城市下拉菜单)。
value
items
DropdownButtonFormField
选择州时,您正在获取城市列表的新列表并将其传递给CityDropDown,但是却忘记了清除先前选择的城市(cityModel)。
cityModel
您还可以参考以下示例:DartPad