flutter - Flutter中对应的DropDownButtonFormFields
问题描述
我正在实现相应的下拉菜单(第二个下拉菜单的选项取决于第一个下拉菜单),它使用这种格式的对象列表:
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),
);
}).toList(),
onChanged: (int newCityId) {
setState(() {
this.selectedCityId = newCityId;
});
},
)
],
当我在此示例中更改状态下拉列表时,我收到一个错误:“应该恰好有一个项目具有 [DropdownButton] 的值:1。检测到零或 2 个或多个 [DropdownMenuItem] 具有相同的值”。
上述错误中的“1”对应于更改状态之前选择的城市值,所以我知道该错误与它仍在寻找旧的 selectedCityId 并且它不再在项目列表中的事实有关,但我不确定为什么我在 setState 中更改了该值。我相信,这个问题的一个关键是,如果我只是将 DropDownButtonFormField 更改为常规 DropDownButtons,那么完全相同的代码就可以工作,但我想使用前者附带的内置标签文本。
解决方案
编辑
您可以使用key: UniqueKey()
int CityDropdownButtonFormField
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(),
decoration: InputDecoration(labelText: 'City'),
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),
);
}).toList(),
onChanged: (int CityId) {
setState(() {
this.selectedCityId = CityId;
});
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
推荐阅读
- laravel - 在响应中添加特定的相关字段
- scala - 拥有多个 Scala SimpleSwingApplication 实例
- python - Twitch Bot URL 恶意软件/病毒检测 PYTHON
- tesseract - 如何在 PA 上更新 Tesseract?
- sql - 如何使 ORACLE SQL 上的值为 0 为空?
- javascript - Google App Scripts - 如何根据另一个单元格清除多个单元格的内容?
- flutter - 实现此主屏幕的最佳方法是什么?
- macos - How to pass value from apple script to shell script in Automator?
- c - Difference between function with returned type pointer and function pointer
- flyway - Flyway 社区版是否支持 Oracle 19.7?