改变两级DropdownButtonFormField 。应该只有一个带有[DropdownButton]值的项目。

问题描述 投票:0回答:1

尽管这里有多个条目似乎有类似的问题,但我不能让这个真正的工作。

我有一个两个依赖的DropdownButtonFormFields的设置,其中第二个改变到另一个列表后,第一个被改变。

  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
══════════════════════════════════════════════════════════════════

我简化了这个例子并重建了错误,以便更好地分析这个问题,并从你们那里得到更多有价值的意见:)

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,
          ),
        ],
      ),
    );
  }
}

Error

forms flutter dropdown
1个回答
0
投票

我发现了一个问题的变通办法。

似乎不是重建DropDownFormField,Flutter只是认为完全可以保留它。在这种情况下,它甚至还相当顽固。

由于我找不到重建Field的方法,所以我创建了一个很讨厌但能用的。也仍然需要一些打磨。

我基本上让flutter相信我每次都提供了一个不同的widget。

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,
            ),
          ],
        ),
      ),
    );
  }
}

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.