我有一个我希望在Flutter中作为下拉列表实现的位置列表。我对这门语言很陌生。这就是我所做的。
new DropdownButton(
value: _selectedLocation,
onChanged: (String newValue) {
setState(() {
_selectedLocation = newValue;
});
},
items: _locations.map((String location) {
return new DropdownMenuItem<String>(
child: new Text(location),
);
}).toList(),
这是我的项目清单:
List<String> _locations = ['A', 'B', 'C', 'D'];
我收到以下错误。
Another exception was thrown: 'package:flutter/src/material/dropdown.dart': Failed assertion: line 468 pos 15: 'value == null || items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not true.
我假设_selectedLocation
的值变为null。但我正在初始化它。
String _selectedLocation = 'Please choose a location';
试试这个
new DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
)
当我遇到这个想要一个不太通用的DropdownStringButton的问题时,我只是创建了它:
dropdown_string_button.dart
FlutterSearchPanel(
padding: EdgeInsets.all(10.0),
selected: 'a',
title: 'Demo Search Page',
data: ['This', 'is', 'a', 'test', 'array'],
icon: new Icon(Icons.label, color: Colors.black),
color: Colors.white,
textStyle: new TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20.0, decorationStyle: TextDecorationStyle.dotted),
onChanged: (value) {
print(value);
},
),
当我用新的动态值替换默认值时,我发生了这种情况。但是,不知何故,您的代码可能依赖于该默认值。因此,请尝试保留一个常量,并将默认值存储在某处以进行回退。
List _currency = ["INR", "USD", "SGD", "EUR", "PND"];
List<DropdownMenuItem<String>> _dropDownMenuCurrencyItems;
String _currentCurrency;
List<DropdownMenuItem<String>> getDropDownMenuCurrencyItems() {
List<DropdownMenuItem<String>> items = new List();
for (String currency in _currency) {
items.add(
new DropdownMenuItem(value: currency, child: new Text(currency)));
}
return items;
}
void changedDropDownItem(String selectedCurrency) {
setState(() {
_currentCurrency = selectedCurrency;
});
}
更改
new Row(children: <Widget>[
new Text("Currency: "),
new Container(
padding: new EdgeInsets.all(16.0),
),
new DropdownButton(
value: _currentCurrency,
items: _dropDownMenuCurrencyItems,
onChanged: changedDropDownItem,
)
])
至
import 'package:flutter/material.dart';
// Subclass of DropdownButton based on String only values.
// Yes, I know Flutter discourages subclassing, but this seems to be
// a reasonable exception where a commonly used specialization can be
// made more easily usable.
//
// Usage:
// DropdownStringButton(items: ['A', 'B', 'C'], value: 'A', onChanged: (string) {})
//
class DropdownStringButton extends DropdownButton<String> {
DropdownStringButton({
Key key, @required List<String> items, value, hint, disabledHint,
@required onChanged, elevation = 8, style, iconSize = 24.0, isDense = false,
isExpanded = false, }) :
assert(items == null || value == null || items.where((String item) => item == value).length == 1),
super(
key: key,
items: items.map((String item) {
return DropdownMenuItem<String>(child: Text(item), value: item);
}).toList(),
value: value, hint: hint, disabledHint: disabledHint, onChanged: onChanged,
elevation: elevation, style: style, iconSize: iconSize, isDense: isDense,
isExpanded: isExpanded,
);
}
_selectedLocation需要成为项目列表的一部分;
首先,让我们来研究一下错误的含义(我已经引用了Flutter 1.2引发的错误,但想法是一样的):
断言失败:第560行pos 15:'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item)=> item.value == value)。length == 1':不是真的。
有四个or
条件。必须至少完成其中一项:
DropdownMenuItem
小部件列表)。这消除了items == null
。items.isEmpty
。_selectedLocation
)。这消除了value == null
。请注意,这是DropdownButton
的值,而不是DropdownMenuItem
的值。因此只留下最后一次检查。归结为:
通过
DropdownMenuItem
迭代。找到所有有value
等于_selectedLocation
的人。然后,检查找到与其匹配的项目数。必须只有一个具有此值的窗口小部件。否则,抛出一个错误。
代码的呈现方式,没有DropdownMenuItem
小部件,其值为_selectedLocation
。相反,所有小部件的值都设置为null
。自null != _selectedLocation
以来,最后一个条件失败了。通过将_selectedLocation
设置为null
来验证这一点 - 应该运行应用程序。
要解决这个问题,我们首先需要在每个DropdownMenuItem
上设置一个值(以便可以将某些内容传递给onChanged
回调):
return DropdownMenuItem(
child: new Text(location),
value: location,
);
该应用程序仍然会失败。这是因为您的列表仍然不包含_selectedLocation
的值。您可以通过两种方式使应用程序工作:
items.where((DropdownMenuItem<T> item) => item.value == value).length == 1
)。如果您想让用户重新选择Please choose a location
选项,可能会有用。hint:
条件)。如果您不希望selectedLocation
仍然是一个选项,这很有用。请参阅下面的代码,说明如何执行此操作:
null
你必须考虑到这一点(来自DropdownButton docs):
“这些项目必须具有不同的值,如果值不为空,则必须包含它们。”
所以基本上你有这个字符串列表
value == null
您在Dropdown值属性中的值初始化如下:
Please choose a location
试试这个清单:
import 'package:flutter/material.dart';
void main() {
runApp(Example());
}
class Example extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
// List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D']; // Option 1
// String _selectedLocation = 'Please choose a location'; // Option 1
List<String> _locations = ['A', 'B', 'C', 'D']; // Option 2
String _selectedLocation; // Option 2
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: DropdownButton(
hint: Text('Please choose a location'), // Not necessary for Option 1
value: _selectedLocation,
onChanged: (newValue) {
setState(() {
_selectedLocation = newValue;
});
},
items: _locations.map((location) {
return DropdownMenuItem(
child: new Text(location),
value: location,
);
}).toList(),
),
),
),
);
}
}
那应该工作:)
如果您不想添加类似的字符串(在列表上下文中),请查看“提示”属性,您可以使用以下内容:
List<String> _locations = ['A', 'B', 'C', 'D'];
您需要在代码中添加String _selectedLocation = 'Please choose a location';
才能使用它。检查List<String> _locations = ['Please choose a location', 'A', 'B', 'C', 'D'];
了。
DropdownButton<int>(
items: locations.map((String val) {
return new DropdownMenuItem<String>(
value: val,
child: new Text(val),
);
}).toList(),
hint: Text("Please choose a location"),
onChanged: (newVal) {
_selectedLocation = newVal;
this.setState(() {});
});
将值放在items.then它将工作,
value: location
您可以使用this类来创建下拉列表:
items: _locations.map((String location) {
return new DropdownMenuItem<String>(
child: new Text(location),
value: location,
);
}).toList(),
请参考这个new DropdownButton<String>(
items:_dropitems.map((String val){
return DropdownMenuItem<String>(
value: val,
child: new Text(val),
);
}).toList(),
hint:Text(_SelectdType),
onChanged:(String val){
_SelectdType= val;
setState(() {});
})
当我试图在下拉列表中显示动态字符串列表时,我遇到了与DropDownButton类似的问题。我最终创建了一个插件:DropDownButton
。不是下拉插件,但您可以使用搜索功能显示项目。
使用以下代码来使用窗口小部件:
...
...
String dropdownValue = 'One';
...
...
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButton<String>(
value: dropdownValue,
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
);
...
...
您获得的错误是由于要求null对象的属性。您的项目必须为null,因此在要求比较其值时,您将收到该错误。检查您是否正在获取数据,或者列表是对象列表而不是简单字符串。