0

我有一个 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()其中包含一个列表 hello,它将过滤掉 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 语句之前提供 hello 列表,它表明该方法where()是在 null 上调用的(我用来过滤的列​​表方法hello()

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();
              
            });
4

1 回答 1

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实际上可以等待特定的未来,而不是通过再次调用您的方法生成的新未来:

FutureBuilder(
        future: dataRetrievalAndFiltering,
        builder: (context, snapshot) {

现在你有一个未来,你可以等待。

于 2020-08-11T07:37:34.977 回答