簡體   English   中英

Dart / Flutter:DropdownButton 在更改值時導致異常

[英]Dart / flutter: DropdownButton causes exception when value is changed

我已經使用DropdownButtonTextField小部件編寫了一個非常廣泛的表單。 這個概念是我有一個StatefulWidget ,其中State<StatefulWidget>包含 2 個返回我想要構建的小部件的方法。 通過這種方式,我可以輕松訪問和使用輸入的數據,並將其傳遞給一個函數,以便從中編寫電子郵件。

但是,當我從選項中選擇一個項目時,框架會在重建過程中引發異常。 我輸入了一些日志函數,它表明setState()方法成功地將值保存到selectedValue變量中。

Widget buildMultiChoiceInputRow(var label, List<String> values) {
    final List<String> options = values.toList();
    selection = options.first;

    final dropDownMenuOptions = options.map((String value) {
      return new DropdownMenuItem<String>(
        value: value,
        child: new Text(value),
      );
    }).toList();

    return new Column(
      children: <Widget>[
        new Row(
          children: <Widget>[
            new Expanded(
              child: new Container(
                  padding:
                      const EdgeInsets.only(left: 5.0, top: 2.0, right: 5.0),
                  child: new Text(label, style: commonInfoCardInfoTextBlack16Bold)),
            ),
          ],
        ),
        new Row(
          children: <Widget>[
            new Expanded(
              child: new Container(
                padding: const EdgeInsets.only(left: 5.0, right: 5.0),
                child: new DropdownButton(
                value: selectedValue,
                items: dropDownMenuOptions,
                onChanged: (selection) {
                  setState(() {
                    selectedValue = selection;
                    switch (label) {
                      case labelVirtualAdoption:
                        tempAdoptionType =
                            composeMultiChoiceAnswer(label, selection);
                            print(selection);
                            print(selectedValue);
                        break;
                          case labelAskedAboutSpecies:
                            tempAskedAboutSpecies =
                                composeMultiChoiceAnswer(label, selection);
                            break;
                          case labelHouseOrFlat:
                            tempHouseOrFlat =
                                composeMultiChoiceAnswer(label, selection);
                            break;
                            ....
                          default:
                            break;
                        }
                      });
                    }),
              ),
            )
          ],
        ),
        new Divider(color: Colors.transparent)
      ],
    );
  }

這是例外:

I/flutter (20998): The following assertion was thrown building AdoptionInput(dirty, state: AdoptionInputState#3cc80):
I/flutter (20998): 'package:flutter/src/material/dropdown.dart': Failed assertion: line 481 pos 15: 'value == null ||
I/flutter (20998): items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not true.

這是堆棧,顯示在重建期間拋出異常:

I/flutter (20998): #2      new DropdownButton (package:flutter/src/material/dropdown.dart)
I/flutter (20998): #3      AdoptionInputState.buildMultiChoiceInputRow (package:osszefogasaszanhuzokert/adoptionPageUtilities.dart:443:28)
I/flutter (20998): #4      AdoptionInputState.build (package:osszefogasaszanhuzokert/adoptionPageUtilities.dart:639:11)
I/flutter (20998): #5      StatefulElement.build (package:flutter/src/widgets/framework.dart:3730:27)
I/flutter (20998): #6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3642:15)
I/flutter (20998): #7      Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (20998): #8      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2242:33)

該問題似乎與之前 flutter 中的錯誤非常相似,但是如果我嘗試在initState()初始化selectionselectedValueinitState()在第一次構建表單時拋出相同的異常。

我在這里缺少什么?

DropdownButton 的“值”應設置為 'null' 或值列表中的一個。

DropdownButton(
      value: null,
      isDense: true,
      onChanged: (String newValue) {
        // somehow set here selected 'value' above whith 
       // newValue
       // via setState or reactive.
      },
      items: ['yellow', 'brown', 'silver'].map((String value) {
        return DropdownMenuItem(
          value: value,
          child: Text(value),
        );
      }).toList(),
    ),

因此,對於我的示例,DropdownButton 值應設置為 null 或“黃色”或“棕色”或“銀色”。

在我被卡住的第二種情況下擴展上述答案。

DropdownButton 的“值”應設置為 'null' 或值列表中的一個。

您的“價值”也應該在每個項目價值中有所不同。

例如:避免這種情況

 items.add(DropdownMenuItem(
  value: 1.toString(),
  child: Text(1.toString()),
));
items.add(DropdownMenuItem(
  value: 1.toString(),
  child: Text(1.toString()),
));

避免重復值。

使用 var 來聲明變量而不是 String。 現在您不需要將默認值設置為 null。

var dropdownvalue;

DropdownButton<String>(
                    value: dropdownvalue,
                    icon: Icon(Icons.keyboard_arrow_down),
                    iconSize: 28,
                    elevation: 20,
                    onChanged: (String newval){
                      setState((){
                        dropdownvalue = newval;
                      });

                    },
                    items: <String>["Registration","Verification", "ArenaRun"]
                        .map<DropdownMenuItem<String>>((String value){
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(value),
                        );
                    }).toList(),
                  ),

有點空閑,但是,當我將 null 作為“值”傳遞時,代碼工作了,但是當我放置一個包含在“項目”中的值時,我遇到了這個問題。 問題是“項目”具有重復的值,因此您似乎應該在傳遞給“項目”的列表中提供所有不同的項目。

這是正確的方法:

 import 'package:flutter/material.dart';

class RegisterFragments extends StatefulWidget {
  RegisterFragments({Key key, this.step}) : super(key: key);
  final int step;

  _RegisterFragmentsState createState() => _RegisterFragmentsState();
}

class _RegisterFragmentsState extends State<RegisterFragments> {
  Map<String, bool> values = {"abc": false, "def": true, "ghi": false};
  List<String> _do = ['One', 'Two', 'Free', 'Four'];
  String _dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    switch (widget.step) {
      case 0:
        return buildDo();
        break;
      case 1:
        return Container(
          child: ListView.builder(
            shrinkWrap: true,
            itemCount: values.length,
            itemBuilder: (BuildContext context, int index) {
              switch (widget.step) {
                case 0:
                  return buildDo();
                  break;
                case 1:
                  return buildService(context, index);
                  break;
                default:
                  return Container();
                  break;
              }
            },
          ),
        );
        break;
      default:
        return Container();
        break;
    }
  }

  Widget buildService(BuildContext context, int index) {
    String _key = values.keys.elementAt(index);

    return Container(
      child: Card(
        child: CheckboxListTile(
          title: Text(_key),
          onChanged: (bool value) {
            setState(() {
              values[_key] = value;
            });
          },
          value: values[_key],
        ),
      ),
    );
  }

  Widget buildDo() {
    return DropdownButton<String>(
      isExpanded: true,
      hint: Text("Service"),
      items: _do.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
      onChanged: (String newValue) {
        setState(() {
          this._dropdownValue = newValue;
        });
      },
      value: _dropdownValue,
    );
  }
}

列表和刪除值

   List<String> _do = ['One', 'Two', 'Free', 'Four'];
   String _dropdownValue = 'One';

下拉項

tems: _do.map<DropdownMenuItem<String>>((String value) {   
  return DropdownMenuItem<String>( ** 
     value: value,
          child: Text(value),
        );
      }).toList(),
      onChanged: (String newValue) {
        setState(() {
          this._dropdownValue = newValue;
        });
      },
      value: _dropdownValue,

我正在做一個 value.toString() 並且 null 被轉換為“null”!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM