在Flutter中更新下拉数据会出错

时间:2019-05-08 19:11:32

标签: asynchronous dart flutter widget dropdown

我正在开发由Flutter中的dropdownbutton组成的小部件。该小部件在请求用户传入的网址后创建dropdownmenuitems

我已经看到正在进行调用并且响应有效,但是当我使用setState更新下拉列表的数据源时,出现以下错误:

  

'package:flutter / src / material / dropdown.dart':断言失败:560行pos 15:'item == null ||   I / flutter(11514):item.isEmpty ||值== null || items.where(((DropdownMenuItem item)=> item.value ==   I / flutter(11514):值)。length== 1':不正确。

我尝试研究此错误,但没有找到有用的答案。代码如下:

class _MyWidgetState extends State<MyWidget> {

List<DropdownMenuItem<String>> _data = [];
String _selected = '';

@override
void initState() {
   super.initState();
   _loadData();
 }
 void _loadData() async {
    if (widget.urlToFetchData.isNotEmpty) {
      var response = await http.get(widget.urlToFetchData);
      if (response.statusCode == 200) {
         Map<String, dynamic> jsonResponse = convert.jsonDecode(response.body);
         jsonResponse.forEach((key, value){
           setState(() {
                  this._data.add(new DropdownMenuItem(
                                  child: new Text(value.toString()),
                                  value: value.toString(),
                             ));
           });
         });
      } else {
         print("Request failed with status: ${response.statusCode}.");
       }
    }
  }
}

@override
Widget build(BuildContext context) {
   if (_data.length == 0) {
      return new Container();
   } else {
        return Column(
            children: <Widget> [
                  new Text(
                    widget.dropdownLabelTitle
                 ),
                DropdownButton(
                     value: _selected,
                     items: _data,
                     hint: new Text(widget.defaultOptionText),
                     onChanged: (value) {
                        _selected = value;
                        widget.valueReturned(_selected);
                        setState(() {

                        });
                     }
                   )
                ],
              );
            }
       }
    }

现在,我完全知道在小部件初始化时,dropdownbutton中的items字段是用一个空列表初始化的,但是我认为通过在http调用结束时调用setState,将会更新该值。 / p>

我尝试了多种更新数据的方法(通过创建本地列表,然后使用addAll或仅通过赋值),但是我遇到相同的错误。

有人知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

您收到此错误,因为下拉菜单试图选择不存在的项目。

DropdownButton(
        value: _selected, # < here you are trying to select `String _selected = '';`
        items: _data,

要解决此简单问题,请删除value或将其放置在某处。

答案 1 :(得分:1)

您的问题确实是由_selected值引起的。它必须在DropdownMenuItem的列表中,因此,在您的情况下,第一个值是一个空字符串,没有任何项目,这样就可以了,但是当您从API获取值时,就没有DropdownMenuItem包含value=='',因此解决方法是使用从API接收到的第一个值来初始化_selected。另外,您应该在setState循环之外for。像这样:

setState(() {
      jsonResponse.forEach((key, value) {
        if (_selected.isEmpty) {
          _selected = value;
        }
        this._data.add(new DropdownMenuItem(
              child: new Text(value.toString()),
              value: value.toString(),
            ));
      });
    });

答案 2 :(得分:0)

这将是可行的。你必须在数组和值中至少插入一个数据。

List<DropdownMenuItem<String>> _data = ['Select One'];
String _selected = _data[0];

或者你可以这样做---->

List<DropdownMenuItem<String>> _data = [];
String _selected = '';
_data.length > 0 ? DropdownButton(
                     value: _selected,
                     items: _data,
                     hint: new Text(widget.defaultOptionText),
                     onChanged: (value) {
                        _selected = value;
                        widget.valueReturned(_selected);
                        setState(() {

                        });
                     }
                   ) : Container();