2017-05-12 2 views
3

HTTP를 통해 JSON 데이터를 가져와 ListView에 표시하고 있습니다. HTTP이기 때문에 모두 비동기입니다. IndexedWidgetBuilder는 동기 함수가 될해야하기 때문에 비동기/HTTP 데이터를 사용하여 IndexedWidgetBuilder에서 하위 위젯을 반환하려면 어떻게해야합니까?

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; 
    }, 
); 

Here's what I'd like to do:

불행하게도,이 작동하지 않습니다. 미래를 사용하여 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을 사용하여 비동기 계산을 기다릴 수 있습니다. 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? 
    ); 
    }, 
); 

좋은 점은 약 FutureBuilder 비동기 요청이 완료하고 국가는 이미 배치 된 곳이 시나리오를 지원한다는 점이다.

+0

내가 이것을 시도한 것은 주목할 만하다. 그러나 너무 복잡하고 느려집니다 (FutureBuilder가 아닌 실제 디자인 덕분에). UI에서 페이지 매김을 숨기려하지 않고 "추가로드"버튼을 추가하기 만했습니다. – perlatus