更改两个级别DropdownButtonFormField:应该只有一个具有[DropdownButton]值的项目 [英] Changing Two Level DropdownButtonFormField : There should be exactly one item with [DropdownButton]'s value

查看:78
本文介绍了更改两个级别DropdownButtonFormField:应该只有一个具有[DropdownButton]值的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管这里有多个条目似乎有类似的问题,但我无法真正使用它。

Despite multiple entries here that seem to have a similar issue i can not get this really working.

我有两个依赖的DropdownButtonFormFields的安装程序,其中第二个更改为第一个被更改后的另一个列表。

I have a Setup of two depended DropdownButtonFormFields where the second changes to another list after the first is changed.


  1. 我能够将问题分解为第二个选择的所选值的持久剩余。我希望它会随着代码中提供的值信息而更改。

提供了以下错误

════════ Exception caught by widgets library ═══════════════════════════════════

There should be exactly one item with [DropdownButton]'s value: GreenBananas. 

Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 827 pos 15: 'items == null || items.isEmpty || value == null ||
              items.where((DropdownMenuItem<T> item) {
                return item.value == value;
              }).length == 1'
The relevant error-causing widget was
    DropdownButtonFormField<String> 
lib/…/testing/test.dart:242
══════════════════════════════════════════════════════════════════

我简化了示例并重建了错误,以便对问题进行更好的分析并从大家那里获得更多有价值的输入信息:)

I simplified the example and reconstructed the error to get a better analyse on the issue and get more valuable input from you guys :)

class InputRowTest extends StatefulWidget {
  @override
  _InputRowTestState createState() => _InputRowTestState();
}

class _InputRowTestState extends State<InputRowTest> {
  List<String> list1 = ['Apples', 'Bananas', 'Peaches'];

  List<String> list1_1 = ['GreenApples', 'RedApples', 'YellowApples'];

  List<String> list1_2 = [
    'YellowBananas',
    'BrownBananas',
    'GreenBananas',
    'GreenApples'
  ];

  List<String> list1_3 = [
    'RedPeaches',
    'YellowPeaches',
    'GreenPeaches',
    'GreenApples'
  ];

  List<String> _fromparent;
  int _fromparentint;
  //String selected;

  @override
  void initState() {
    _fromparent = list1_1;
    _fromparentint = 0;
    //selected = list1[0];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    List<List<String>> subLists = [list1_1, list1_2, list1_3];
    _fromparent = subLists[_fromparentint];

    DropdownButtonFormField ddff = DropdownButtonFormField(
      //value: selected, //list1[0],
      //items: list1.map((category) {
      value: _fromparent[0], //Seems this value wont change.
      items: _fromparent.map((category) {
        return DropdownMenuItem(
          value: category,
          child: Container(
            child: Text(category),
          ),
        );
      }).toList(),
      onChanged: (val) => print(val),
    );

    return Center(
      child: Row(
        children: <Widget>[
          Expanded(
            child: DropdownButtonFormField(
              value: list1[0],
              items: list1.map((category) {
                return DropdownMenuItem(
                  value: category,
                  child: Container(
                    child: Text(category),
                  ),
                );
              }).toList(),
              onChanged: (val) {
                setState(() {
                  //selected = val;
                  _fromparentint = list1.indexOf(val);
                });
              },
            ),
          ),
          Expanded(
            child: ddff,
          ),
        ],
      ),
    );
  }
}

推荐答案

我找到了解决此问题的方法。

I found a workarround on the issue.

Flutter似乎没有重建DropDownFormField,而是认为完全可以保留它。在这种情况下,它甚至还很固执。

It seems like instead of rebuilding the DropDownFormField, Flutter just considers it as completely ok to keep it. In this case it is also even pretty stubborn.

由于我找不到重建该字段的方法,因此创建了一个非常讨厌但可以工作的字段。

As i could not find a way to rebuild the Field, I created a pretty nasty but working. Also still requires some polish.

我基本上让flutter相信我每次都提供不同的小部件。

I basically let flutter believe I provide a different widget each time.

class InputRowTest extends StatefulWidget {
  @override
  _InputRowTestState createState() => _InputRowTestState();
}

class _InputRowTestState extends State<InputRowTest> {
  List<String> list1 = ['Apples', 'Bananas', 'Peaches'];

  List<String> list1_1 = ['GreenApples', 'RedApples', 'YellowApples'];

  List<String> list1_2 = [
    'YellowBananas',
    'BrownBananas',
    'GreenBananas',
    'GreenApples'
  ];

  List<String> list1_3 = [
    'RedPeaches',
    'YellowPeaches',
    'GreenPeaches',
    'GreenApples'
  ];

  List<String> _fromparent;
  int _fromparentint;
  Widget ddbff;
  var selected;
  bool chance;

  Widget ddff(List<String> list, bool chance) {
    return (chance)
        ? DropdownButtonFormField(
            value: list[0], //Seems this value wont change.
            items: list.map((category) {
              return DropdownMenuItem(
                value: category,
                child: Container(
                  child: Text(category),
                ),
              );
            }).toList(),
            onChanged: (val) {
              print(val);
            },
          )
        : Container(
            child: DropdownButtonFormField(
              value: list[0], //Seems this value wont change.
              items: list.map((category) {
                return DropdownMenuItem(
                  value: category,
                  child: Container(
                    child: Text(category),
                  ),
                );
              }).toList(),
              onChanged: (val) {
                print(val);
              },
            ),
          );
  }

  @override
  void initState() {
    _fromparent = list1_1;
    _fromparentint = 0;
    selected = list1_1[0];
    chance = true;
    ddbff = ddff(_fromparent, chance);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    List<List<String>> subLists = [list1_1, list1_2, list1_3];
    _fromparent = subLists[_fromparentint];

    chance = !chance;
    ddbff = ddff(_fromparent, chance);

    return Center(
      child: Container(
        child: Row(
          children: <Widget>[
            Expanded(
              child: DropdownButtonFormField(
                value: list1[0],
                items: list1.map((category) {
                  return DropdownMenuItem(
                    value: category,
                    child: Container(
                      child: Text(category),
                    ),
                  );
                }).toList(),
                onChanged: (val) {
                  setState(() {
                    _fromparentint = list1.indexOf(val);
                  });
                },
              ),
            ),
            Expanded(
              child: ddbff,
            ),
          ],
        ),
      ),
    );
  }
}

这篇关于更改两个级别DropdownButtonFormField:应该只有一个具有[DropdownButton]值的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆