как я могу добавить ленивую загрузку в этот список? - PullRequest
3 голосов
/ 23 апреля 2020

Это то, как я получаю посты в postList из firebase firestore, мне нужна функция, которая работает, чтобы получать больше постов при прокрутке. Следующий набор сообщений должен начинаться после последнего сообщения, отображаемого в этом первоначальном списке, и добавляться в этот список по мере того, как пользователь прокручивает, пока в пожарном хранилище есть сообщения.

class _FeedScreenState extends State<FeedScreen> {
  List<Post> _posts = [];
   ScrollController _controller = ScrollController();

  @override
  void initState() {
    super.initState();
    _setupFeed();
     _controller.addListener(_scrollListener);
  }

_scrollListener() {
    setState(() {
      if (_controller.position.atEdge) {
        if (_controller.position.pixels == 0) {


        } else {
          _getMore();

        }
      }
    });
  }
  _setupFeed() async {
    List<Post> posts = await DatabaseService.getFeedPosts(widget.currentUserId);
    setState(() {
      _posts = posts;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        title: Text(
          'New List',
          style: TextStyle(
            color: Colors.black,
            fontSize: 35.0,
          ),
        ),
      ),
      body: RefreshIndicator(
        onRefresh: () => _setupFeed(),
        child: ListView.builder(
          controller: _controller,
          itemCount: _posts.length,
          itemBuilder: (BuildContext context, int index) {
            Post post = _posts[index];
            return FutureBuilder(
              future: DatabaseService.getUserWithId(post.authorId),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                if (!snapshot.hasData) {
                  return SizedBox.shrink();
                }
                User author = snapshot.data;
                return PostView(
                  currentUserId: widget.currentUserId,
                  post: post,
                  author: author,
                );
              },
            );
          },
        ),
      ),
    );
  }
}

вот так я получаю список сообщений

static Future<List<Post>> getFeedPosts(String userId) async {
    QuerySnapshot feedSnapshot = await feedsRef
        .document(userId)
        .collection('userFeed')
        .orderBy('timestamp', descending: true)
        .limit(30)
        .getDocuments();
    List<Post> posts =
        feedSnapshot.documents.map((doc) => Post.fromDoc(doc)).toList();
    return posts;
  }

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

na2axl ответ был почти верно. Я добавлю здесь объяснение и пример использования startAfter()

Если вы посмотрите документацию по нумерации страниц , вы увидите, что вам нужно использовать startAfter() со ссылкой на любой фильтр, который вы используемый. В вашем случае вы заказываете, используя timestamp, поэтому ваш следующий запрос должен выглядеть следующим образом:

static Future<List<Post>> getNextFeedPosts(String userId, TimeStamp timestamp) async {
    QuerySnapshot feedSnapshot = await feedsRef
        .document(userId)
        .collection('userFeed')
        .orderBy('timestamp', descending: true)
        //Here you need to let Firebase know which is the last document you fetched
        //using its timesTamp
        .startAfter(timestamp)
        .limit(30)
        .getDocuments();
    List<Post> posts =
        feedSnapshot.documents.map((doc) => Post.fromDoc(doc)).toList();
    return posts;
  }

Это означает, что ваш следующий запрос все равно будет заказан на timestamp, но первый полученный документ будет после timestamp на startAfter

Надеюсь, это поможет, однако вы можете проверить документацию, поскольку есть и другие примеры!

2 голосов
/ 23 апреля 2020

Я думаю, что решение этой проблемы решит вашу проблему:

Вы должны отредактировать ваши getFeedPosts для сбора ваших сообщений, начиная с заданного индекса:

Я не знаком с FireStore Я нашел startAt() метод в документах

РЕДАКТИРОВАТЬ: я неправильно понял концепцию Firestore, поэтому я изменил startAt() на startAfter() после Франсиско Хавьер Snchez совет

static Future<List<Post>> getFeedPosts(String userId, TimeStamp start) async {
  QuerySnapshot feedSnapshot = await feedsRef
      .document(userId)
      .collection('userFeed')
      .orderBy('timestamp', descending: true)
      .startAfter(start)
      .limit(30)
      .getDocuments();
  List<Post> posts =
      feedSnapshot.documents.map((doc) => Post.fromDoc(doc)).toList();
  return posts;
}

Теперь вы можете запросить его так:

_getMore() async {
  // You have to give the timestamp of the last post here
  // Change this line by the right way...
  List<Post> posts = await DatabaseService.getFeedPosts(widget.currentUserId, _posts[_posts.length - 1].timestamp);
  setState(() {
    // Do += instead of =, += will add fetched posts to the current list, = will overwrite the whole list
    _posts += posts;
  });
}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...