Asynchronous 更新颤振中的下拉数据会产生错误

Asynchronous 更新颤振中的下拉数据会产生错误,asynchronous,dart,flutter,widget,dropdown,Asynchronous,Dart,Flutter,Widget,Dropdown,我正在开发一个小部件,它由flatter中的下拉按钮组成。此小部件在向用户传入的url发出请求后创建dropdownmenuitems 我看到调用正在进行,响应有效,但当我使用setState更新下拉列表的数据源时,出现以下错误: “package:flatter/src/material/dropdown.dart”:失败的断言:第560行位置15:“items==null”|| I/flatter(11514):items.isEmpty | | value==null | | | item

我正在开发一个小部件,它由flatter中的
下拉按钮
组成。此小部件在向用户传入的url发出请求后创建
dropdownmenuitems

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

“package:flatter/src/material/dropdown.dart”:失败的断言:第560行位置15:“items==null”|| I/flatter(11514):items.isEmpty | | value==null | | | items.where((DropdownMenuItem item)=>item.value== I/flatter(11514):值。长度==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(() {

                        });
                     }
                   )
                ],
              );
            }
       }
    }
class\u MyWidgetState扩展状态{
列表_data=[];
字符串_selected='';
@凌驾
void initState(){
super.initState();
_loadData();
}
void\u loadData()异步{
if(widget.urlToFetchData.isNotEmpty){
var response=wait http.get(widget.urlToFetchData);
如果(response.statusCode==200){
Map jsonResponse=convert.jsonDecode(response.body);
forEach((键,值){
设置状态(){
此._data.add(新下拉菜单项(
子项:新文本(value.toString()),
value:value.toString(),
));
});
});
}否则{
打印(“请求失败,状态:${response.statusCode}”);
}
}
}
}
@凌驾
小部件构建(构建上下文){
如果(_data.length==0){
返回新容器();
}否则{
返回列(
儿童:[
新文本(
widget.dropdownLabelTitle
),
下拉按钮(
值:_已选定,
项目:_数据,
提示:新文本(widget.defaultOptionText),
一旦更改:(值){
_所选=值;
widget.valueReturned(_选中);
设置状态(){
});
}
)
],
);
}
}
}
现在,我完全知道在小部件初始化时,dropdownbutton中的items字段是用一个空列表初始化的,但是我认为在http调用完成时调用setState,将更新该值

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


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

您遇到此错误是因为下拉菜单试图选择不存在的项

DropdownButton(
        value: _selected, # < here you are trying to select `String _selected = '';`
        items: _data,
下拉按钮(
值:_selected,#<这里您试图选择'String'u selected=''`
项目:_数据,

要解决此问题,请删除
或将其设置在某个位置。

您的问题确实是由所选的
值引起的。它必须位于
下拉菜单项的列表中
,因此在您的情况下,第一个值是一个空字符串,没有任何项,因此这是可以的,但是当您从API获取值时,没有e> DropdownMenuItem
具有
值==''
,因此修复方法是使用从API接收到的第一个值初始化所选的
。此外,您还应该
for
循环之外设置状态

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

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

List<DropdownMenuItem<String>> _data = ['Select One'];
String _selected = _data[0];
List_data=[“选择一个”];
字符串_selected=_数据[0];

或者您可以这样做-->

List_data=[];
字符串_selected='';
_data.length>0?下拉按钮(
值:_已选定,
项目:_数据,
提示:新文本(widget.defaultOptionText),
一旦更改:(值){
_所选=值;
widget.valueReturned(_选中);
设置状态(){
});
}
):容器();

当我在解析json后删除
setState
语句时,我没有得到错误。为什么这可以解决我的问题?当第一次执行构建方法时,选择的
也是空的,我没有得到错误。如果
\u data
\u selected
是空的,你不会得到任何错误。@Nuts你怎么办意思是将其设置在
值的某个位置。我们应该将
值确切地放置在哪里。_selected的初始值为
'
,因此它必须存在一个具有该值的下拉菜单项。是否确实存在?在更新下拉按钮项列表时,在
\u selected
中传递
null
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();