一尘不染

有没有一种方法可以通过使用FirestoreRecyclerAdapter组合查询游标来对查询进行分页?

java

我有一个查询,看起来像这样:

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?这有可能吗?


阅读 213

收藏
2020-09-08

共1个答案

一尘不染

正如@FrankvanPuffelen在您之前的问题]中已经回答的那样,您无法实现这一点,因为在您的情况下,您应该将2个不同的查询(firstsecond)传递给单个适配器,而使用不能实现FirestoreRecyclerAdapter。您可以将第一个查询或第二个查询与适配器的单个实例一起使用。

一种解决方案是创建两个不同的列表,包含每个查询的结果并将其组合。然后,您可以将结果列表传递给另一个适配器(假设为)ArrayAdapter,然后将结果显示为ListView,甚至更好地显示为RecyclerView。在这种情况下,问题是您将无法使用FirestoreRecyclerAdapter该类提供的实时功能,但是这种方法可以解决您的问题。

编辑:

根据您在注释部分的请求,我将为您提供一个示例,该示例如何使用a ListView和an
以最简单的方式对按钮单击进行分页ArrayAdapter。您也可以RecyclerView在向下滚动时使用a来实现相同的目的。但是为了简单起见,假设我们有一个ListView和一个Button,并且希望在每次单击按钮时将更多项目加载到列表中。为此,让我们先定义视图:

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在用户滚动时以较小的块显示它们的解决方案。

2020-09-08