仅在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;
          });
        });

这是我的FutureBuilderbuild()方法中调用的方法,但是,如果我在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) {

现在您有了一个可以等待的未来。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...