Flutter DropdownButton-从其余Web服务填充项目

时间:2019-03-05 12:39:50

标签: asynchronous combobox dart flutter

我的fetchCities()方法返回Future<List<City>>,并从其余Web服务加载数据。填充项目的代码:

 Widget buildCitiesSelector(){

    return new Center(
        child: FutureBuilder(
            future: fetchCities() ,
            builder: (context, snapshot){
              if (snapshot.hasData) {
                return new DropdownButton <City>(
                    hint: Text('Wybierz miasto'),
                  items: snapshot.data.map<DropdownMenuItem<City>>((City value) {
                    return DropdownMenuItem<City>(
                      value: value,
                      child: Text(value.name),
                    );
                  }).toList(),
                  onChanged: (value) {
                      setState(() {_selectedCity = value;});
                  },
                  value: _selectedCity,
                );
              }
              else{
                return CircularProgressIndicator();
              }
            }

        )

    );
  }

结果:项目正确显示在选择器中。但是,在选择任何特定项目时,我会遇到异常:

  

I / flutter(13910):W小组件库引起的异常提示   ╞═════════════════════════════════════════════════ ══════════我/扑   (13910):引发以下断言   FutureBuilder>(脏,状态:I / flutter(13910):   _FutureBuilderState>#dacd9):I / flutter(13910):'package:flutter / src / material / dropdown.dart':断言失败:行   560 pos 15:“项目== null || I / flutter(13910):item.isEmpty ||   值== null || items.where(((DropdownMenuItem item)=> item.value   == I / flutter(13910):值)。长度== 1':不正确。

如何正确选择项目?有什么想法吗?

4 个答案:

答案 0 :(得分:0)

在这种情况下,您不应使用FutureBuilder。而是获取initState()中的数据,然后使用setState()进行重建以更新视图。

如果fetchCities()每次都被创建一个新的Future,则build()将在每次UI重建时调用该取回操作(这很常见)

https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html

  

将来一定要早一些,例如在State.initState期间,...

答案 1 :(得分:0)

今天我遇到了同样的问题,经过一番挖掘,我发现我的代码有一个错误:DropdownButton中的值不在项目列表中。

我(错误地)认为下拉列表将处理“空”值-事实并非如此。

答案 2 :(得分:0)

      child: FutureBuilder(
            future: Webservice().load(Country.countries) ,
            builder: (context, snapshot){
              if(snapshot.hasError)
                return Text(snapshot.error);

              if (snapshot.hasData) {
                return  DropdownButtonFormField(
                  decoration: new InputDecoration(icon: Icon(Icons.language)), //, color: Colors.white10
                  value: selectedCountry,
                  items: snapshot.data.map<DropdownMenuItem<Country>>((Country country) {

                       return  DropdownMenuItem<Country>(

                                value: country,
                                child: Text(country.name, style: TextStyle(color: Color.fromRGBO(58, 66, 46, .9))),

                              );
                  })
                          .toList(),


                  onChanged: (Country newValue) {
                      setState(() => selectedCountry = newValue);
                      // selectedCountry = newValue;
                      print(newValue.id);
                      print(newValue.name);
                  },
               );

              }
              return CircularProgressIndicator();

答案 3 :(得分:0)

您可以声明一个Future并在initState和initState中使用此Future进行初始化。

City cityModel;
Future _future;

@override
  void initState() {
    _future = fetchCities();
    super.initState();
  }

body: FutureBuilder<List<City>>(
          future: _future,