我通过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;
},
);
不幸的是,这不起作用,因为IndexedWidgetBuilder必须是同步函数。如何使用Future为IndexedWidgetBuilder构建子级?似乎没有办法wait for the future to complete同步。
以前,我在返回子窗口小部件之前将数据加载到数组中,而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吗?
答案 0 :(得分:9)
您可以使用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
的好处是,它会处理异步请求完成且状态已被处理的情况。