问题描述
我正在实现相应的下拉菜单(其中第二个下拉菜单的选项取决于第一个下拉菜单,该下拉菜单类似)使用以下格式的对象列表:
List<State> states = [
new State(stateId: 1,stateName: "New York",cities: [
new City(cityId: 1,cityName: "New York City"),new City(cityId: 2,cityName: "buffalo") ...
小部件代码如下:
children: <Widget>[
DropdownButtonFormField<int>(
decoration: Inputdecoration(labelText: 'State'),value: selectedStateId,items: states.map((State state) {
return new DropdownMenuItem<int>(
value: state.stateId,child: new Text(states.singleWhere((x) => x.stateId == state.stateId).stateName),);
}).toList(),onChanged: (int newStateId) {
setState(() {
this.selectedCityId = states.singleWhere((x) => x.stateId == newStateId).cities[0].cityId; // set to first city for this state
this.selectedStateId = = newStateId;
});
},),DropdownButtonFormField<int>(
decoration: Inputdecoration(labelText: 'City'),value: selectedCityId,items: states.singleWhere((x) => x.stateId == selectedStateId)
.cities
.map((City city) {
return new DropdownMenuItem<int>(
value: city.cityId,child: new Text(states
.singleWhere((x) => x.stateId == selectedStateId).cities.singleWhere((x) => x.cityId == city.cityId).cityName),onChanged: (int newCityId) {
setState(() {
this.selectedCityId = newCityId;
});
},)
],
在此示例中,当更改“状态”下拉菜单时,出现错误: “应该只包含[DropdownButton]值的一项:1。 检测到零个或两个或两个以上具有相同值的[DropdownMenuItem]。
上述错误中的“ 1”对应于更改状态之前所选城市的值,因此我知道该错误与以下事实有关:该城市仍在寻找旧的selectedCityId,并且不再在项目列表,但是我不确定为什么在setState中更改了该值。我认为,解决此问题的关键是,如果我只是将DropDownButtonFormField更改为常规的DropDownButtons,则可以使用相同的确切代码,但是我想使用前者随附的内置标签文本。
解决方法
修改
您可以使用key: UniqueKey()
个城市DropdownButtonFormField
DropdownButtonFormField<int>(
key: UniqueKey(),decoration: InputDecoration(labelText: 'City'),
您可以在下面复制粘贴运行完整代码
您可以将selectedStateId
和selectedCityId
设置为states
的属性
您不能直接设置为selectedStateId = 1
之类的值,因为系统会比较地址
代码段
int selectedStateId;
int selectedCityId;
@override
void initState() {
selectedStateId = states[0].stateId;
selectedCityId = states[0].cities[0].cityId;
super.initState();
}
工作演示
完整代码
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',theme: ThemeData(
primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: MyHomePage(title: 'Flutter Demo Home Page'),);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key,this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class City {
int cityId;
String cityName;
City({this.cityId,this.cityName});
}
class CountryState {
int stateId;
String stateName;
List<City> cities;
CountryState({this.stateId,this.stateName,this.cities});
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
List<CountryState> states = [
CountryState(stateId: 1,stateName: " York",cities: [
City(cityId: 1,cityName: "York City"),City(cityId: 2,cityName: "Buffalo")
]),CountryState(stateId: 2,stateName: "A",cities: [
City(cityId: 3,cityName: "A1"),City(cityId: 4,cityName: "A2")
])
];
int selectedStateId;
int selectedCityId;
@override
void initState() {
selectedStateId = states[0].stateId;
selectedCityId = states[0].cities[0].cityId;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
DropdownButtonFormField<int>(
decoration: InputDecoration(labelText: 'State'),value: selectedStateId,items: states.map((CountryState state) {
return DropdownMenuItem<int>(
value: state.stateId,child: Text(states
.singleWhere((x) => x.stateId == state.stateId)
.stateName),);
}).toList(),onChanged: (int StateId) {
setState(() {
this.selectedCityId = states
.singleWhere((x) => x.stateId == StateId)
.cities[0]
.cityId; // set to first city for this state
this.selectedStateId = StateId;
});
},DropdownButtonFormField<int>(
key: UniqueKey(),value: selectedCityId,items: states
.singleWhere((x) => x.stateId == selectedStateId)
.cities
.map((City city) {
return DropdownMenuItem<int>(
value: city.cityId,child: Text(states
.singleWhere((x) => x.stateId == selectedStateId)
.cities
.singleWhere((x) => x.cityId == city.cityId)
.cityName),onChanged: (int CityId) {
setState(() {
this.selectedCityId = CityId;
});
},)
],floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,tooltip: 'Increment',child: Icon(Icons.add),);
}
}
,
我将这个示例发布在Flutter的问题板上,他们无法在最新的稳定版本(此评论中为1.20.2)上重复。我升级了flutter版本(我使用的是1.17.1),并且相同的代码没有问题,因此对于遇到相同问题的任何人,我建议您更新flutter版本。