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。检测到零个或两个或两个以上具有相同值的[DropdownMenuItem]”。

上面的错误中的“ 1”对应于更改状态之前所选城市的值,因此我知道该错误与以下事实有关:该城市仍在寻找旧的selectedCityId,并且不再在项目列表中,但是我不确定为什么在setState中更改了该值。我认为,解决此问题的关键是,如果我只是将DropDownButtonFormField更改为常规的DropDownButtons,则可以使用相同的精确代码,但是我想使用前者随附的内置标签文本。

chunhunghan

编辑
可以使用key: UniqueKey()int CityDropdownButtonFormField

DropdownButtonFormField<int>(
      key: UniqueKey(),
      decoration: InputDecoration(labelText: 'City'),

您可以在下面复制粘贴运行完整代码。
您可以将selectedStateId设置selectedCityIdstates的属性,
不能直接设置为,例如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),
      ),
    );
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在多对多表中获取对应和不对应的值

来自分类Dev

R中列表中向量的对应比较

来自分类Dev

新GCM中对应的GCMRegistrar.isRegistered()

来自分类Dev

ReactJS和Flux中的$ resource对应项

来自分类Dev

获取与js对象中的值对应的键

来自分类Dev

合并数组JS中的对应对象

来自分类Dev

WiX 3.8中的ActionText表对应什么

来自分类Dev

如何从表中删除重复/对应的值?

来自分类Dev

python中是否有与“ \”相对应的函数?

来自分类Dev

删除sql表中不对应的行

来自分类Dev

Windows 10中与右键对应的键盘字符

来自分类Dev

ReactJS和Flux中的$ resource对应项

来自分类Dev

在每个对应元素中打印数组

来自分类Dev

BSD中ps --forest的对应物

来自分类Dev

如何使java中的按钮与textField对应?

来自分类Dev

C中的对应表达式

来自分类Dev

R中单独数组中的乘积对应矩阵

来自分类Dev

从Ruby哈希中的对应键中检索值

来自分类Dev

将字母与Jython中列表中的对应数字匹配

来自分类Dev

如何基于list()中的对应值替换dataframe()中的值?

来自分类Dev

比较各个行中的值与不同列中的对应行

来自分类Dev

返回编号与Excel中数组中的条目相对应

来自分类Dev

从Ruby哈希中的对应键中检索值

来自分类Dev

在AngularJS中的json对象中提取对应的值

来自分类Dev

从超类函数中的对应子类快速调用类函数

来自分类Dev

在与Clockpicker对应的文本框中设置时间

来自分类Dev

PostgreSQL货币(或数字?)类型及其在Scala(Java)中的对应类型

来自分类Dev

合并3个列表中的3个对应项

来自分类Dev

提取对应于记忆中某个值的多行