Flutter 如何将延迟加载添加到此列表中?

Flutter 如何将延迟加载添加到此列表中?,flutter,Flutter,这就是我如何从firebase firestore获取postList中的帖子的方法,我需要一个函数来获取更多scroll上的帖子。下一组帖子必须在该初始列表中显示的最后一篇帖子之后开始,并在用户滚动时添加到此列表,只要firestore中有帖子 class _FeedScreenState extends State<FeedScreen> { List<Post> _posts = []; ScrollController _controller = Scr

这就是我如何从firebase firestore获取postList中的帖子的方法,我需要一个函数来获取更多scroll上的帖子。下一组帖子必须在该初始列表中显示的最后一篇帖子之后开始,并在用户滚动时添加到此列表,只要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,
                );
              },
            );
          },
        ),
      ),
    );
  }
}
class\u FeedScreenState扩展状态{
列表_posts=[];
ScrollController_controller=ScrollController();
@凌驾
void initState(){
super.initState();
_setupFeed();
_controller.addListener(_scrollListener);
}
_scrollListener(){
设置状态(){
if(_controller.position.atEdge){
如果(_controller.position.pixels==0){
}否则{
_getMore();
}
}
});
}
_setupFeed()异步{
List posts=await DatabaseService.getFeedPosts(widget.currentUserId);
设置状态(){
_职位=职位;
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
背景颜色:Colors.white,
标题:正文(
"新名单",,
样式:TextStyle(
颜色:颜色,黑色,
字体大小:35.0,
),
),
),
正文:刷新指示器(
onRefresh:()=>\u setupFeed(),
子项:ListView.builder(
控制器:_控制器,
itemCount:_posts.length,
itemBuilder:(构建上下文,int索引){
Post Post=_posts[索引];
回归未来建设者(
未来:DatabaseService.getUserWithId(post.authorId),
生成器:(BuildContext上下文,异步快照){
如果(!snapshot.hasData){
返回SizedBox.shrink();
}
用户作者=snapshot.data;
返回后视图(
currentUserId:widget.currentUserId,
岗位:岗位,,
作者:作者,,
);
},
);
},
),
),
);
}
}
这就是我获取帖子列表的方式

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;
  }
static Future getfeedpost(字符串userId)异步{
QuerySnapshot feedSnapshot=等待feedsRef
.document(userId)
.collection('userFeed')
.orderBy('timestamp',降序:true)
.限额(30)
.getDocuments();
列出职位=
feedSnapshot.documents.map((doc)=>Post.fromDoc(doc)).toList();
返回岗位;
}

我认为这样做可以解决您的问题:

您必须编辑getFeedPosts以收集从给定索引开始的帖子:

我对FireStore不熟悉,我在文档中找到了
startAt()
方法

编辑:我误解了Firestore的概念,所以我按照Francisco Javier Snchez的建议将
startAt()
更改为
startAfter()

static Future getFeedPosts(字符串userId,时间戳start)异步{
QuerySnapshot feedSnapshot=等待feedsRef
.document(userId)
.collection('userFeed')
.orderBy('timestamp',降序:true)
.startAfter(开始)
.限额(30)
.getDocuments();
列出职位=
feedSnapshot.documents.map((doc)=>Post.fromDoc(doc)).toList();
返回岗位;
}
现在可以这样查询:

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;
  }
\u getMore()异步{
//你必须在这里给出最后一篇文章的时间戳
//用正确的方法更改这行。。。
List posts=await DatabaseService.getFeedPosts(widget.currentUserId,_posts[_posts.length-1]。时间戳);
设置状态(){
//Do+=代替=,+=将把回帖添加到当前列表,=将覆盖整个列表
_职位+=职位;
});
}
希望这会有帮助

na2axl的答案几乎是正确的。我将在这里添加如何使用
startAfter()

如果选中,您将看到需要使用
startAfter()
引用您使用的任何筛选器。在您的案例中,您使用的是
时间戳
,因此您的下一个查询应该如下所示:

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;
  }
static Future getNextFeedPosts(字符串userId,TimeStamp TimeStamp)异步{
QuerySnapshot feedSnapshot=等待feedsRef
.document(userId)
.collection('userFeed')
.orderBy('timestamp',降序:true)
//在这里,您需要让Firebase知道您获取的最后一个文档是哪一个
//使用它的时间戳
.startAfter(时间戳)
.限额(30)
.getDocuments();
列出职位=
feedSnapshot.documents.map((doc)=>Post.fromDoc(doc)).toList();
返回岗位;
}
这意味着您的下一个查询仍将按
时间戳
排序,但检索到的第一个文档将在
开始之后的
时间戳
之后


我希望这有帮助,但是,您可以检查文档,因为还有其他示例

目前的行为是什么?没有添加帖子?或者帖子列表完全改变了?我将限制设置为30,所以帖子列表中会加载30篇帖子,但如何在滚动页面上加载更多帖子?因为如果我不设置限制,那么它将加载集合中的所有帖子。但这将如何从最初加载的列表中的最后一篇帖子之后开始获取帖子?@notabot它将使用当前加载的列表长度(最初为30)在30篇帖子之后获取接下来的30篇帖子。当您第二次滚动到末尾时,加载的帖子数量将为60篇,因此调用此方法将在60篇帖子之后获取接下来的30篇帖子,以此类推…@na2axl只是想让您知道,startAt和startAfter指的是您在orderBy中使用的字段。如果您试图将startIndex提供给时间戳,它将失败。@FranciscoJavierSnchez很抱歉我误解了这个概念,我已经更新了我的答案,但是我如何提及startAfter(此处最后一个fecthed文档的时间戳)?我如何提及最后一个fecthed文档的时间戳