Android中如何判断QuerySnapshot已到数据末尾?解决分页崩溃问题
解决Firestore数据加载末尾时的数组越界崩溃问题
问题根源
你遇到的ArrayIndexOutOfBoundsException其实很好理解:当Firestore查询已经到数据末尾时,返回的QuerySnapshot里没有任何文档(也就是value.size() = 0),但你依然执行了value.getDocuments().get(value.size() -1)——这时候value.size()-1等于-1,直接触发数组越界报错。
解决方案
我们只需要在尝试获取最后一个可见文档前,先判断当前QuerySnapshot是否包含数据,同时维护一个标记变量追踪是否还有更多数据,就能避免无效查询和崩溃。
步骤1:添加全局标记变量
在你的Activity/Fragment类里加一个布尔变量,用来标记是否还有更多帖子可以加载:
private boolean hasMorePosts = true; // 默认设为true,认为有更多数据
步骤2:修改nextFirestore方法的逻辑
在处理QuerySnapshot时先做非空检查,只有当有数据时才继续处理;如果没有数据,就更新标记并提示用户:
public void nextFirestore(DocumentSnapshot lastVisible) { // 如果已经没有更多数据,直接返回,避免发起无效查询 if (!hasMorePosts) { Toast.makeText(this, "已经加载完所有帖子啦", Toast.LENGTH_SHORT).show(); return; } CollectionReference questionRef = db.collection("posts"); mQuery = questionRef.startAfter(lastVisible) .limit(20); mRegistration = mQuery.addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException e) { if (e != null) { Log.w(TAG, "Listen failed.", e); return; } // 先判断QuerySnapshot是否为空 if (value == null || value.isEmpty()) { hasMorePosts = false; // 更新标记,说明没有更多数据了 Toast.makeText(Post.this, "已经加载完所有帖子啦", Toast.LENGTH_SHORT).show(); return; } List<Posts> realtimeList = new ArrayList<>(); for (DocumentSnapshot doc : value) { Posts post = doc.toObject(Posts.class); assert post != null; post.postId = doc.getId(); realtimeList.add(post); // 这里注意你原代码写的是add(question),应该是add(post)哦 } // 现在可以安全获取lastVisible文档了 DocumentSnapshot lastVisibleDoc = value.getDocuments().get(value.size() - 1); Log.d(TAG, "next last visible: " + lastVisibleDoc); showPosts(realtimeList, lastVisibleDoc); } }); }
步骤3:在用户确认加载时检查标记
当用户在第20条帖子的对话框选择“继续”时,先判断hasMorePosts是否为true,只有为true时才调用查询方法:
// 假设这是你的对话框确认逻辑 dialog.setPositiveButton("继续", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (hasMorePosts) { nextFirestore(lastVisibleDoc); // 传入之前保存的lastVisible文档对象 } else { Toast.makeText(Post.this, "已经没有更多帖子了", Toast.LENGTH_SHORT).show(); } } });
额外小提醒
你原代码里有个笔误:realtimeList.add(question);应该是realtimeList.add(post);,不然会把错误的对象添加到列表里,记得修正这个小问题哦!
内容的提问来源于stack exchange,提问作者Jack Wilson
相关产品推荐
相关产品推荐

