一尘不染

Firestore异步加载并填充ListView抖动

flutter

嗨,我正尝试从firestore中获取数据并填充listview,以下是我的代码,但是由于我的异步调用未完成,我遇到了异常,我如何等待该asyn调用完成并填充我的listview,我的代码如下:

    import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:test_flutter/pkg/Feed.dart';

class FeedLoader {
  final CollectionReference _colReference;

  FeedLoader(Firestore _firestore)
      : _colReference = _firestore.collection(Feed.getDocumentName()) {}

  Future<List<Feed>> load() async {
    final List<Feed> feeds = new List<Feed>();
    await for (QuerySnapshot qs in _colReference.snapshots) {
      for (DocumentSnapshot ds in qs.documents) {
        feeds.add(Feed.fromJson(ds.data));
      }
      return feeds;
    }
    return feeds;
  }
}

这是我的小部件

    import 'package:flutter/material.dart';
import 'package:test_flutter/pkg/FeedLoader.dart';
import 'package:test_flutter/pkg/Feed.dart';

class FeedWidget extends StatefulWidget {
  final FeedLoader feedLoader;

  const FeedWidget({Key key, this.feedLoader}) : super(key: key);

  createState() => new FeedWidgetState(feedLoader);
}

class FeedWidgetState extends State<FeedWidget> {
  final List<Feed> _feeds = new List<Feed>();
  final FeedLoader _feedLoader;
  final TextStyle fontStyle = const TextStyle(fontSize: 16.0);

  FeedWidgetState(this._feedLoader);

  @override
  Widget build(BuildContext context) {
    print(_feedLoader == null);
    _feedLoader
        .load()
        .then((feeds) => () {
              print("Got call back now");
              _feeds.addAll(feeds);
            })
        .catchError((e) => handleError(e));

    print("Feeds size ${_feeds}");
    return _buildListView(context);
  }

  void handleError(e) {
    print("FeedLoaderException ${e}");
  }

  Widget _buildListView(BuildContext context) {
    return new ListView.builder(
      padding: const EdgeInsets.all(6.0),
      itemBuilder: (context, i) {
        if (i.isOdd) return new Divider();

        final index = i ~/ 2;
//        pagination
//        if (index >= contents.length) {
//          contents.addAll(generateWordPairs().take(10));
//        }
        return _buildRowContent(context, _feeds[i]);
      },
    );
  }

  Widget _buildRowContent(BuildContext context, Feed content) {
    return new ListTile(
      title: new Text(
        "${content.getTitle()}",
        style: fontStyle,
      ),
    );
  }
}

阅读 273

收藏
2020-08-13

共1个答案

一尘不染

您可以使用StreamBuilderFutureBuilder异步构建窗口小部件

你可以例如做

return new StreamBuilder(
   stream: Firestore....snapshot,
   builder: (context, snapshot) {
      if (snapshot.hasData) {
         final feeds = snapshot.data.map(Feed.fromJson);
         return new ListView(
              ....
         );
      }
   },
)
2020-08-13