Flutter DropdownButton - 从 REST Web 服务填充项目
Posted
技术标签:
【中文标题】Flutter DropdownButton - 从 REST Web 服务填充项目【英文标题】:Flutter DropdownButton - populate items from rest webservice 【发布时间】:2019-07-26 22:24:57 【问题描述】:我的 fetchCities()
方法返回 Future<List<City>>
并从 rest webservice 加载数据。填充项目的代码:
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):══╡ 小部件库发现异常 ╞═════════════════════════════════════════════════ ══════════ I/颤振 (13910):以下断言被抛出构建 FutureBuilder>(脏,状态:I/flutter(13910): _FutureBuilderState>#dacd9): I/flutter (13910): 'package:flutter/src/material/dropdown.dart': 断言失败:行 560 位置 15: '项目 == 空 ||我/颤振(13910):items.isEmpty || 值 == 空 || items.where((DropdownMenuItem item) => item.value == I/flutter (13910): value).length == 1': 不正确。
如何正确选择项目?有什么想法吗?
【问题讨论】:
我觉得你的问题和我的很相似:***.com/questions/61720324/… 【参考方案1】:在这种情况下,您不应使用FutureBuilder
。而是获取initState()
中的数据,然后使用setState()
进行重建以更新视图。
如果 fetchCities()
每次调用时都会创建一个新的 Future
,那么 build()
将在每次重新构建 UI 时调用该 fetch(可能非常频繁)
https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html
未来一定是更早获得的,例如在 State.initState 期间,...
【讨论】:
为什么不使用FutureBuilder
?我设法在initState
中获得了未来的城市列表(通过调用我的fetchCities
方法,然后将检索到的列表传递给FutureBuilder
,但它不起作用。
@user1209216 遵循此答案并检查来自DropdownMenuItem
的value:
必须是某种id,要比较的东西你不能像你在问题中那样比较对象。跨度>
我实际上认为这种方法没有问题。在 initState
中检索到的未来,传递给 FutureBuilder
。我刚刚将 fetchCities
移至 initState【参考方案2】:
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】:我今天遇到了同样的问题,经过一番挖掘,我发现我的代码中有一个错误:DropdownButton 中的值不在项目列表中。
我(错误地)假设下拉菜单会处理“空”值 - 但事实并非如此。
【讨论】:
【参考方案4】:您可以在 initState 中声明 Future 和 init,并在 FutureBuilder 中使用这个未来。
City cityModel;
Future _future;
@override
void initState()
_future = fetchCities();
super.initState();
body: FutureBuilder<List<City>>(
future: _future,
【讨论】:
以上是关于Flutter DropdownButton - 从 REST Web 服务填充项目的主要内容,如果未能解决你的问题,请参考以下文章
Dart / flutter:DropdownButton在值更改时导致异常
Flutter - 如何在小部件测试中选择 DropdownButton 项
Flutter GetBuilder Dependent DropDownButton - 即使值已被重置,也应该只有一项具有 [DropdownButton] 的值
如何像 Flutter 中的 Spinner 一样在 DropdownButton 下方打开 DropDown 对话框?