我有一个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();
});
答案 0 :(得分:0)
您多次调用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) {
现在您有了一个可以等待的未来。