如何使用async/HTTP数据在IndexedWidgetBuilder中返回子窗口小部件?

per*_*tus 5 dart flutter

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

这是我想做的事情:

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;
  },
);
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用,因为IndexedWidgetBuilder必须是一个同步函数.如何使用Future为IndexedWidgetBuilder构建子级?似乎没有办法等待未来同步完成.

以前,我正在将数据加载到数组中,仅检查 IndexedWidgetBuilder函数以查看返回子窗口小部件之前是否存在列表元素.

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

这有效,但我想将视图与数据完全分开,并根据需要异步请求JSON.

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

Col*_*son 9

您可以使用a等待异步计算FutureBuilder.我可能会改变你PostPreviewFuture作为构造函数参数并把它放在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?
    );
  },
);
Run Code Online (Sandbox Code Playgroud)

好处FutureBuilder是它负责处理异步请求完成并且状态已经处理掉的情况.