【问题标题】:Error: Either zero or 2 or more [DropdownMenuItem]s were detected with the same value I/flutter (18363): 'package:flutter/src/material/dropdown.dart':错误:检测到 0 个或 2 个或多个 [DropdownMenuItem] 具有相同的值 I/flutter (18363):'package:flutter/src/material/dropdown.dart':
【发布时间】:2019-12-25 00:12:51
【问题描述】:

Error code 嗨,我是 Flutter 的新手,并且有一个关于下拉按钮的问题,关于对多个下拉按钮使用相同的值。

根据我对错误的理解,这是由于在同一活动中为 2 个或更多下拉按钮使用了相同的列表。

我怎样才能解决这个错误,但仍然能够为 2 个或更多下拉按钮重复使用列表?

  String _value1;
  String _value2;

  final List<String> nameList = <String>[
    "Name1",
    "Name2",
    "Name3",
    "Name4",
    "Name5",
    "Name6",
    "Name7",
    "Name8"
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 2.0,
        title: Text('Hello'),
      ),
      body:  ListView(
            children: <Widget>[
              Row(
                children: <Widget>[
                  Text('Name: '),
                  Center(
                    child: DropdownButton(
                      value: _value1,
                      onChanged: (value) {
                        setState(() {
                          _value1 = value;
                        });
                      },
                      items: nameList.map(
                        (item) {
                          return DropdownMenuItem(
                            value: item,
                            child: new Text(item),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ],
              ),
              Row(
                children: <Widget>[
                  Text('Name: '),
                  Center(
                    child: DropdownButton(
                      value: _value2,
                      onChanged: (value) {
                        setState(() {
                          _value2 = value;
                        });
                      },
                      items: nameList.map(
                        (item) {
                          return DropdownMenuItem(
                            value: item,
                            child: new Text(item),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ],
              ),
            ],
          ),
      backgroundColor: Colors.grey[200],
    );
  }
}

【问题讨论】:

  • 即使我可以证明带有密钥的 DropdownMenuItem 仅实例化一次,我仍然遇到此问题。我花了好几天的时间来解决这个问题。

标签: flutter


【解决方案1】:

我遇到了完全相同的错误,多个下拉列表都来自同一个静态列表,唯一的区别是在我的例子中,它是一个对象列表,而不是字符串。

所以,如果它是一个静态列表,它不可能是空的,列表中没有重复值,并且您已经确定 value 不为空?那么剩下的唯一选择就是item.value 不同于value

在我的例子中,因为它是一个对象列表,所以我必须覆盖我的 Object 类中的 operator ==hashcode 方法。

bool operator ==(dynamic other) =>
      other != null && other is TimeSelection && this.hour == other.hour;

  @override
  int get hashCode => super.hashCode;

就是这样。我不必初始化_value1_value2

【讨论】:

  • 这应该被标记为已接受的答案。添加相等和 hashCode 函数为我解决了这个问题。我将一个对象从一个页面传递到另一个页面,并且碰巧传递到新页面的对象的实例与从新页面中的列表创建的对象不同,即使它们都是由相同的数据构造的。
  • 我创建了我的对象列表的副本,并将这个新列表标记为最终列表。效果很好
  • 同意。我有同样的问题,使用自定义对象的单个列表,我按照上面的方法并在我的自定义对象中覆盖了 == 和哈希码,工作了一个冠军。
  • @MonstersX 你能分享一下你是如何在你的自定义对象中添加覆盖 === 和哈希码的代码
  • 如果你有很多类需要这个,查看 Equatable 包pub.dev/packages/equatable 它会更容易。
【解决方案2】:

你有这个异常是因为错误:

  1. 没有_value1_value2初始化。
  2. 当您初始化它们时,请确保 _value1_value2 直接来自 nameList,例如
_value1 = nameList[0];
_value2 = nameList[3];

这是复杂数据类型的重要步骤,但在您的情况下

_value1 = "Name1";
_value2 = "Name4";

足够了。

完整示例:

  String _value1;
  String _value2;

  final List<String> nameList = <String>[
    "Name1",
    "Name2",
    "Name3",
    "Name4",
    "Name5",
    "Name6",
    "Name7",
    "Name8"
  ];

  /// initialization is here:
  @override
 void initState() {
    super.initState();
    _value1 = nameList[0];
    _value2 = nameList[3];
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Row(
          children: <Widget>[
            Text('Name: '),
            Center(
              child: DropdownButton(
                value: _value1,
                onChanged: (value) {
                  setState(() {
                    _value1 = value;
                  });
                },
                items: nameList.map(
                  (item) {
                    return DropdownMenuItem(
                      value: item,
                      child: new Text(item),
                    );
                  },
                ).toList(),
              ),
            ),
          ],
        ),
        Row(
          children: <Widget>[
            Text('Name: '),
            Center(
              child: DropdownButton(
                value: _value2,
                onChanged: (value) {
                  setState(() {
                    _value2 = value;
                  });
                },
                items: nameList.map(
                  (item) {
                    return DropdownMenuItem(
                      value: item,
                      child: new Text(item),
                    );
                  },
                ).toList(),
              ),
            ),
          ],
        ),
      ],
    );
  }
}

【讨论】:

    【解决方案3】:

    您收到该异常是因为 _value1 和 _value2 未初始化并且为下拉小部件提供空值。

    你可以这样做:

    DropdownButton(
      value: _value1.isNotEmpty ? _value1 : null, // guard it with null if empty
      items: nameList.map((item) {
               return DropdownMenuItem(
                  value: item,
                  child: new Text(item),
               );
             }).toList(), 
    );
    

    【讨论】:

      【解决方案4】:

      我有同样的问题,我解决了。 下拉按钮需要项目列表和值。我们定义了items和selected items,但是item selected instance不在items list里面。

      你应该试试这个并修正你的逻辑。 (值是用户选择的项目值)

       var _value = itemList.isEmpty
          ? value
          : itemList.firstWhere((item) => item.value == value.value);
      

      更多:https://gist.github.com/VB10/fd560694fec0a38751e798a213408001

      【讨论】:

      • 完美答案,救了我的命
      【解决方案5】:

      您必须初始化_value1_value2 并确保这些值也存在于nameList 中。

      【讨论】:

      • 一个关键的事情是确保这些值也存在于 nameList 中。解决了我的问题
      • 简单有效!
      • 如此简单却又如此实用!
      【解决方案6】:

      我的解决方案比其他所有解决方案都简单。找到一个与列表中不同的值的事实是因为我在变量中放置了一个 value ,它既不是满的也不是空的,值是这个( "") 并且对于 Dropdown 值实例,它必须为 null。所以,我只是在变量的声明中放了一个 null 值。比如:“String _value;”,瞧,它奏效了。

      #对不起,这里是英语,巴西人。

      【讨论】:

        【解决方案7】:

        您必须使用初始值初始化_value1_value2

        【讨论】:

          【解决方案8】:

          _value1_value2 变量需要初始化,或者你可以这样做:

          value: _value1 != null ? _value1 : null,
          hint: Text('Your hint'),
          

          【讨论】:

            【解决方案9】:

            var _issues = [ “订阅相关”, “谈话疗法相关”, “程序相关”, “账户相关”, “技术相关”, ];

            String _currentSelectedValue=_issues.first;

            【讨论】:

              【解决方案10】:

              Getx 包也有同样的问题。更新时,会导致此错误,因为将相同的项目添加到列表中。将key: UniqueKey() 添加到DropdownButtonFormField 是我的解决方案。

              【讨论】:

              • 嘿伙计,感谢您的回答,但您能否分享示例代码,因为我在使用 GetX 包时遇到了同样的问题。非常感谢
              【解决方案11】:

              就我而言,我使用包flutter_form_builderFormBuilderDropdown。 在小部件FormBuilderDropdown 中添加key: UniqueKey() 是我的情况的解决方案。

              【讨论】:

              • 这对我有用,我也遇到了那个包的问题。
              • 但是这个插件没有给出 onChanged() 方法
              • @s.j 这个包中也提供了onChanged()方法。
              【解决方案12】:

              尽管接受的答案可能有效,但它是不必要的,而且效果过大。

              您需要做的就是确保您初始化的值也在列表中。那就是:

              String _value1 = "Name1";

              如果初始化的值不在您的列表中,您将收到您收到的错误消息。期间!

              【讨论】:

                【解决方案13】:

                如果您确定您的代码是正确的,请执行“热重启”而不是“热重载”。

                【讨论】:

                  【解决方案14】:

                  您可以在多个DropDownButton 中使用同一个列表。您得到的错误是因为列表中有多个相同的值。 例如,如果我将列表更改为下面给出的列表,其中两个项目具有相同的值,则会引发错误。

                  `final List<String> nameList = <String>[
                      "Name1",
                      "Name1",
                      "Name3",
                      "Name4",
                      "Name5",
                      "Name6",
                      "Name7",
                      "Name8"
                    ];`
                  

                  错误:

                  【讨论】:

                  • 嗯,但就我而言,我已确保列表中的值是唯一的,但感谢您的反馈!
                  【解决方案15】:

                  _value1_value2 必须在您的列表中

                  【讨论】:

                    【解决方案16】:

                    这在我的情况下解决了

                    value: _value1,
                        onChanged: (value) {
                          setState(() {
                            _value1 = value;
                            _value2 = null;
                          });
                        },
                    

                    【讨论】:

                      【解决方案17】:

                      dropdownbuttonformfield 过滤机制使用单个字段进行过滤。它不能按类哈希过滤。将 DropdownMenuItem 值设置为传入数据的键。 dropdownmenuItem 值必须是唯一的。关键是字符串类型。 currentStatus 是下拉列表中定位的关键。我将类具有databaseValue 字段和displayValue 字段的类对象列表映射到下拉菜单作为value:databaseValue 和child:Text(displayValue)。现在,我可以将 _currentStatus 设置为 databaseValue,它将位于下拉列表中。

                      String _currentStatus;
                      
                      List<DropdownMenuItem> listMenuItems =
                        <DropdownMenuItem<String>>[];
                      
                      Provider.of<Api>(context, listen: false)
                          .getComboViews()
                          .then((data) {
                        setState(() {
                          listMenuItems =
                              data.map<DropdownMenuItem<String>>((item) {
                            return DropdownMenuItem<String>(
                                value: item.databaseValue, child: Text(item.displayValue));
                          }).toList();
                      
                      
                       DropdownButtonFormField<String>( 
                           value: this._currentStatus,
                           items: listMenuItems
                           onChanged: (String value) {
                                 setState(() {
                                 this._currentStatus = value;
                          });
                        );
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2020-05-12
                        • 2023-02-16
                        • 2023-01-26
                        • 2011-09-29
                        • 2022-08-17
                        • 2015-11-13
                        • 2021-11-09
                        • 1970-01-01
                        相关资源
                        最近更新 更多