如何将 async/HTTP 数据用于 IndexedWidgetBuilder 中的 return 子窗口小部件?

How do I use async/HTTP data to return child widgets in an IndexedWidgetBuilder?

我正在通过 HTTP 获取 JSON 数据并将其显示在 ListView 中。因为是HTTP,所以都是异步的。

Here's what I'd like to do:

var index = new ListView.builder(
  controller: _scrollController,
  itemBuilder: (ctx, i) async {
    _log.fine("loading post $i");
    var p = await _posts[i];
    return p == null ? new PostPreview(p) : null;
  },
);

不幸的是,这不起作用,因为 IndexedWidgetBuilder has to be a synchronous function. How do I use a Future to build a child for an IndexedWidgetBuilder? It doesn't seem like there's a way to 是同步的。

之前,我将数据加载到一个数组中,并且 IndexedWidgetBuilder 函数仅 checked to see if the list elements existed 在返回子窗口小部件之前。

var index = new ListView.builder(
  controller: _scrollController,
  itemBuilder: (ctx, i) {
    _log.fine("loading post $i");
    return _posts.length > i ? new PostPreview(_posts[i]) : null;
  },
);

这可行,但我想将视图与数据完全分离并根据需要异步请求 JSON。

根据我有限的经验,这似乎也是一个常见的用例。可以将 IndexWidgetBuilder 的异步版本添加到 flutter 中吗?

您可以使用 FutureBuilder 等待异步计算。我可能会更改您的 PostPreview 以将 Future 作为构造函数参数并将 FutureBuilder 放在那里,但是如果您想按原样保留 PostPreview,方法如下修改你的 itemBuilder.

var index = new ListView.builder(
  controller: _scrollController,
  itemBuilder: (ctx, i) {
    return new FutureBuilder(
      future: _posts[i],
      builder: (context, snapshot) {
        return snapshot.connectionState == ConnectionState.done
               ? new PostPreview(snapshot.data)
               : new Container(); // maybe a show placeholder widget?
    );
  },
);

FutureBuilder 的好处在于它会处理异步请求完成并且您的状态已被处理的场景。