java - 有没有办法通过使用 FirestoreRecyclerAdapter 组合查询游标来对查询进行分页?
问题描述
我有一个看起来像这样的查询:
Query first = ref.orderBy("name", Query.Direction.ASCENDING).limit(10);
这就是我将数据显示到我的RecyclerView
.
firestoreRecyclerOptions = new FirestoreRecyclerOptions.Builder<ModelClass>().setQuery(query, ModelClass.class).build();
myFirestoreRecyclerAdapter = new MyFirestoreRecyclerAdapter(firestoreRecyclerOptions);
recyclerView.setAdapter(myFirestoreRecyclerAdapter);
我正在尝试使用此处指定的分页,但无法解决。
first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
DocumentSnapshot lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1);
Query second = ref.orderBy("name", Query.Direction.ASCENDING).startAfter(lastVisible).limit(10);
//Create a firestoreRecyclerOptions and setting the adapter
}
});
有没有办法通过组合查询游标来对查询进行分页FirestoreRecyclerAdapter
?这甚至可能吗?
解决方案
正如@FrankvanPuffelen 已经在您之前的问题中回答的那样,您无法实现这一点,因为在您的情况下,您应该将 2 个不同的查询 ( first
and second
) 传递给单个适配器,而FirestoreRecyclerAdapter
. 您可以将第一个查询或第二个查询与适配器的单个实例一起使用。
一个解决方案是创建两个不同的列表,包含每个查询的结果并将它们组合起来。然后您可以将结果列表传递给另一个适配器,比如说 anArrayAdapter
然后将结果显示到 aListView
甚至更好的 a 中RecyclerView
。这种情况下的问题是您将无法使用该类提供的实时功能,FirestoreRecyclerAdapter
但这种方法将解决您的问题。
编辑:
根据您在评论部分的要求,我将给您一个示例,说明如何使用 aListView
和 an以最简单的方式对按钮单击的查询进行分页ArrayAdapter
。RecyclerView
向下滚动时也可以使用 a 来实现相同的目的。但是为了简单起见,假设我们有 aListView
和 aButton
并且我们希望在每次单击按钮时将更多项目加载到列表中。为此,让我们首先定义视图:
ListView listView = findViewById(R.id.list_view);
Button button = findViewById(R.id.button);
假设我们有一个如下所示的数据库结构:
Firestore-root
|
--- products (collection)
|
--- productId (document)
|
--- productName: "Product Name"
还有一个看起来像这样的模型类:
public class ProductModel {
private String productName;
public ProductModel() {}
public ProductModel(String productName) {this.productName = productName;}
public String getProductName() {return productName;}
@Override
public String toString() { return productName; }
}
现在,让我们定义一个限制设置为 的查询3
。
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference productsRef = rootRef.collection("products");
Query firstQuery = productsRef.orderBy("productName", Query.Direction.ASCENDING).limit(3);
这意味着每次单击按钮时,我们将再加载 3 个项目。现在,这里是神奇的代码:
firstQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<ProductModel> list = new ArrayList<>();
for (DocumentSnapshot document : task.getResult()) {
ProductModel productModel = document.toObject(ProductModel.class);
list.add(productModel);
}
ArrayAdapter<ProductModel> arrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, list);
listView.setAdapter(arrayAdapter);
lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Query nextQuery = productsRef.orderBy("productName", Query.Direction.ASCENDING).startAfter(lastVisible).limit(3);
nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> t) {
if (t.isSuccessful()) {
for (DocumentSnapshot d : t.getResult()) {
ProductModel productModel = d.toObject(ProductModel.class);
list.add(productModel);
}
arrayAdapter.notifyDataSetChanged();
lastVisible = t.getResult().getDocuments().get(t.getResult().size() - 1);
}
}
});
}
});
}
}
});
其中lastVisible
是DocumentSnapshot
表示查询中最后一个可见项的对象。在这种情况下,每隔三分之一,它被声明为 gloabl 变量:
private DocumentSnapshot lastVisible;
Edit2:
在这里,您还可以获得有关如何从 Firestore 数据库中获取数据并在RecyclerView
用户滚动时以较小的块显示它的解决方案。
推荐阅读
- android - 升级 android studio 导致我的颤振应用程序只显示白屏
- vue.js - 如何在 VueJs 中使用过滤器来过滤输入值?
- java - Vaadin 14 - Grid::setClassNameGenerator 不起作用
- java - 找不到应用创建的 .jpg 文件的位置
- c# - AutoMapper 在嵌套列表中设置属性 Null
- vba - 如何引用使用 Access VBA 不可见的子表单值?
- python - Dask:从另一个用户读取 sql 表
- c# - SimpleInjector:根据作用域变量选择数据库
- keyboard - 可以在 Windows 10 中关闭右 ctrl 键吗?
- c# - 从浮点数组中获取字节而不进行分配(即通过强制转换)