仅在FutureBuilder获取snapshot.data后如何加载列表?

时间:2020-08-11 07:11:31

标签: flutter dart future flutter-futurebuilder

我有一个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();
              
            });

1 个答案:

答案 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) {

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