如何在列表视图中滚动添加更多项目? [英] How do i add more items on scroll in the listview?

查看:57
本文介绍了如何在列表视图中滚动添加更多项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码当前将加载Firestore集合中存储的所有啤酒.我如何才能最初仅加载10个啤酒,然后在用户向下滚动并到达10个啤酒列表的末尾时再加载.它应该在最后一次冲泡之后再加载10个.并且应根据时间戳对冲泡进行排序.

This code here currently loads all the brews that are stored in the Firestore collection.. How can i load initially just 10 brews and then later on when the user scrolls down and reaches to the end of the list of 10 brews..it should load 10 more after the last brew..and the brews should be sorted according to the timestamp.

class BrewList extends StatefulWidget {
  @override
  _BrewListState createState() => _BrewListState();
}

class _BrewListState extends State<BrewList> {
  List<Brew> brews = [];
   ScrollController _controller = ScrollController();

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

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


        } else {



        }
      }
    });
  }



 _startFirst() async {
    brews = await DatabaseService().brews ?? [];
    setState(() {
      brews = brews;

    });
  }

  @override
  Widget build(BuildContext context) {
    Future<void> _refreshBrews() async {
      List<Brew> tempList = await DatabaseService().brews;
      setState(() {
        brews = tempList;
      });
      print(brews);
    }


    return RefreshIndicator(
      onRefresh: _refreshBrews,
      child: ListView.builder(
        controller: _controller,
        itemCount: brews.length,
        itemBuilder: (context, index) {
          return BrewTile(brew: brews[index]);
        },
      ),
    );
  }
}


Future<List<Brew>> get brewss async {
    QuerySnapshot snapshot = await brewsCollection
        .orderBy('timestamp', descending: true)
          .limit(2)
        .getDocuments();

    return _postListFromSnapshot(snapshot);
  }

推荐答案

不确定以下内容是否有帮助,但这是我在flutter应用程序中所做的事情.请特别注意底部的_onScroll函数.

Not sure if the following will help, but here's what I did in my flutter app. Pay special attention to the _onScroll function at the bottom.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../blocs/feed_bloc/feed_events.dart';
import '../../blocs/feed_bloc/bloc.dart';
import '../../blocs/feed_bloc/feed_state.dart';
import './post.dart';
import '../loader.dart';

class Feed extends StatefulWidget {
  Feed({ Key key }): super(key: key);

  @override
  _FeedState createState() => _FeedState();
}

class _FeedState extends State<Feed> {
  final _scrollController = ScrollController();
  final _scrollThreshold = 300.0;
  FeedBloc _feedBloc;

  _FeedState();

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
    _feedBloc = BlocProvider.of<FeedBloc>(context);
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<FeedBloc, FeedState>(
      builder: (context, state) {
        if (state is FeedUninitialized) {
          _feedBloc.add(Init());
          return Loader();
        }

        if (state is FeedLoading) {
          return Loader();
        }

        if (state is FeedLoaded) {
          return new RefreshIndicator(
            child: ListView(
              controller: _scrollController,
              // Important: Remove any padding from the ListView.
              padding: EdgeInsets.zero,
              children: state.posts.map((post) {
                return Post(
                  postModel: state.postMap[post]
                );
              }).toList(),
            ),
            onRefresh: () {
              _feedBloc.add(Refresh());
              return new Future.delayed(new Duration(seconds: 1));
            },
          );
        }


        return Center(
          child: SizedBox(
            height: 33,
            child: Text(
              'Sorry, there was a problem loading the feed.',
              style: TextStyle( color: Colors.white)
            ),
          ),
        );
      }
    );
  }

  int lastScroll = 0;
  void _onScroll() {
    if (new DateTime.now().millisecondsSinceEpoch - lastScroll > 1000) {
      lastScroll = new DateTime.now().millisecondsSinceEpoch;
      final maxScroll = _scrollController.position.maxScrollExtent;
      final currentScroll = _scrollController.position.pixels;
      if (maxScroll - currentScroll <= _scrollThreshold) {
        _feedBloc.add(Fetch());
      }
    }
  }
}

我认为您需要的是startAfterDocument.见下文...

I think what you need is startAfterDocument. See below...

Future<Map<String, dynamic>> getPosts({PostModel parent, PostModel lastPost}) async {
    // First, we create the initial query. 
    // We pass in the parent key if there is one.
    Query query = Firestore.instance
      .collection('posts');

      if (parent != null) {
        query = query.where('parentId', isEqualTo: parent.key);
      } else {
        query = query.where('parentId', isNull: true);
      }

      query = query.orderBy('timestamp', descending: true);

    // If we want to start at a certain doc (user is scrolling throught he feed)
    // then we specify to start after a certain doc
    if (lastPost != null) {
      query = query.startAfterDocument(lastPost.rawDoc);
    }

    // Execute the query
    final results = await query
      .limit(18)
      .getDocuments();

    // Create some Lists/Maps we're going to need
    List<String> posts = new List<String>();
    Map<String, PostModel> postMap = new Map<String, PostModel>();
    Map<String, bool> likeMap = new Map<String, bool>();

    // Convienience/Brevity 
    final List<DocumentSnapshot> documents = results.documents;
    final int numDocs = documents.length;

    if (numDocs > 0) {
      final firstDoc = results.documents[0].data;
      final lastDoc = results.documents[numDocs-1].data;

      // Get all your likes for a certain date range that aligns with the
      // documents we just retrieved
      likeMap = await getLikes(firstDoc['postCreated'], lastDoc['postCreated']);
    }

    // Loop through, and create all the PostModels
    for (int i = 0; i < numDocs; i++) {
      DocumentSnapshot doc = documents[i];
      PostModel post = snapshotToPostModel(doc, likeMap[doc.documentID]);
      postMap[doc.documentID] = post;
      posts.add(post.key);
    }

    final Map<String, dynamic> res = new Map<String, dynamic>();

    res['posts'] = posts;
    res['postMap'] = postMap;

    return res;
  }

这篇关于如何在列表视图中滚动添加更多项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆