2017-05-12 50 views
3

我通過HTTP獲取JSON數據並將其顯示在ListView中。由於它是HTTP,所有都是異步的。如何使用異步/ HTTP數據在IndexedWidgetBuilder中返回子窗口小部件?

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必須是同步的功能。我如何使用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添加到撲動中嗎?

回答

5

您可以等待使用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的是,它的異步請求完成,其中,你的國家已經佈置照顧的情景。

+0

值得注意的是,我試過這個,它確實有效。然而,它變得太複雜和緩慢(不是由於FutureBuilder,而是我的一般設計)。 我最終只是添加了「加載更多」按鈕,而不是試圖從UI中隱藏分頁。 – perlatus

相關問題