如何解决仅在FutureBuilder获取snapshot.data后如何加载列表?
我有一个JSON方法,完成后会返回List
,
Future<List<Feed>> getData() async {
List<Feed> list;
String link =
"https://example.com/json";
var res = await http.get(link);
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["feed"] as List;
list = rest.map<Feed>((json) => Feed.fromJson(json)).toList();
}
return list;
}
然后我在包含列表问候的initState()
中调用它,它将过滤掉JSON列表,但是首先在屏幕上显示了一个null
列表,几秒钟后加载列表。
getData().then((usersFromServer) {
setState(() {. //Rebuild once it fetches the data
hello = usersFromServer
.where((u) => (u.category.userJSON
.toLowerCase()
.contains('hello'.toLowerCase())))
.toList();
users = usersFromServer;
filteredUsers = users;
});
});
这是我的FutureBuilder
在build()
方法中调用的方法,但是,如果我在return语句之前提供问候列表,则表明我在空值上调用了方法where()
(我用来过滤hello()
的list方法)
FutureBuilder(
future: getData(),builder: (context,snapshot) {
return snapshot.data != null ?
Stack(
children: <Widget>[
CustomScrollView(slivers: <Widget>[
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,mainAxisSpacing: 10.0,crossAxisSpacing: 10.0,childAspectRatio: 4.0,),delegate: SliverChildBuilderDelegate(
(BuildContext context,int index) {
return Container(
child: puzzle[0],);
},childCount: 1,)
]),],)
:
CircularProgressIndicator();
});
解决方法
您多次调用getData方法。不要那样做您的UI等待一个呼叫,而您的代码等待另一个。真是一团糟。叫它一次,然后等待那个呼叫。
您需要定义在您所在的州等待的未来:
Future<void> dataRetrievalAndFiltering;
然后在您的initstate
中,将整个操作分配给此将来:
(请注意,我完全删除了setState,在此不再需要)
dataRetrievalAndFiltering = getData().then((usersFromServer) {
hello = usersFromServer.where((u) => (u.category.userJSON.toLowerCase().contains('hello'.toLowerCase()))).toList();
users = usersFromServer;
filteredUsers = users;
});
现在您的FurtureBuilder
实际上可以等待那个特定的未来,而不是等待您通过再次调用方法生成的新的Future:
FutureBuilder(
future: dataRetrievalAndFiltering,builder: (context,snapshot) {
现在您有了一个可以等待的未来。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。