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),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'),

您可以在下面复制粘贴运行完整代码
您可以将selectedStateIdselectedCityId设置为states的属性
您不能直接设置为selectedStateId = 1之类的值,因为系统会比较地址
代码段

  int selectedStateId;
  int selectedCityId;

  @override
  void initState() {
    selectedStateId = states[0].stateId;
    selectedCityId = states[0].cities[0].cityId;
    super.initState();
  }

工作演示

enter image description here

完整代码

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版本。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...