Dart / flutter:DropdownButton在值更改时导致异常
Posted
技术标签:
【中文标题】Dart / flutter:DropdownButton在值更改时导致异常【英文标题】:Dart / flutter: DropdownButton causes exception when value is changed 【发布时间】:2018-10-27 07:23:00 【问题描述】:我使用DropdownButton
和TextField
小部件编写了一个相当广泛的表单。这个概念是我有一个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)
问题似乎与a former bug in flutter 非常相似,但是如果我尝试在initState()
中初始化selection
和selectedValue
,则会在第一次构建表单时抛出相同的异常。
我在这里错过了什么?
【问题讨论】:
与此同时,我发现当构建具有与“igen”“nem”不同的值(或者我认为与我使用的第一个不同)的小部件时会引发异常 【参考方案1】: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 或为“黄色”或“棕色”或“银色”。
【讨论】:
但是在 make select: null 之后,选择的值没有显示在下拉列表中 是选择的值未显示?有什么办法可以解决这个问题【参考方案2】:用我被卡住的第二种情况扩展上述答案。
DropdownButton 的“值”应设置为“null”或值列表中的一个。
您的“价值”也应该在每个项目的价值中有所不同。
例如:避免这种情况
items.add(DropdownMenuItem(
value: 1.toString(),
child: Text(1.toString()),
));
items.add(DropdownMenuItem(
value: 1.toString(),
child: Text(1.toString()),
));
避免重复值。
【讨论】:
【参考方案3】:使用 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(),
),
【讨论】:
【参考方案4】:有点休息时间,但是,当我将 null 作为“值”传递时,代码可以工作,但是当我放置一个包含在“项目”中的值时,我遇到了这个问题。问题是“Items”具有重复值,因此您似乎应该提供传递给“Items”的列表中的所有不同项目。
【讨论】:
【参考方案5】:这是正确的方法:
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 和 dorpdown 值
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,
【讨论】:
请添加 cmets 并突出显示您所做的与海报不同的部分。【参考方案6】:我正在执行 value.toString() 并且 null 被转换为“null”!
【讨论】:
以上是关于Dart / flutter:DropdownButton在值更改时导致异常的主要内容,如果未能解决你的问题,请参考以下文章