如何使用Android对Firestore进行分页?

我阅读了Firestore文档以及Internet(stackoverflow)上有关Firestore分页的所有文章,但没有运气。我试图在文档中实现确切的代码,但是什么也没有发生。我有一个包含项目的基本数据库(超过1250个或更多),我想逐步获取它们。通过滚动以加载15个项目(到数据库中的最后一个项目)。

如果使用文档代码:

// Construct query for first 25 cities, ordered by population

Query first = db.collection("cities")

.orderBy("population")

.limit(25);

first.get()

.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {

@Override

public void onSuccess(QuerySnapshot documentSnapshots) {

// ...

// Get the last visible document

DocumentSnapshot lastVisible = documentSnapshots.getDocuments()

.get(documentSnapshots.size() -1);

// Construct a new query starting at this document,

// get the next 25 cities.

Query next = db.collection("cities")

.orderBy("population")

.startAfter(lastVisible)

.limit(25);

// Use the query for pagination

// ...

}

});

怎么做?文档没有太多细节。

PS:当用户滚动时,我需要使用回收站视图(而不是列表视图)。谢谢

回答:

正如官方文档中提到的那样,解决此问题的关键是使用startAfter()方法。因此,你可以通过将查询游标与limit()方法结合使用来对查询进行分页。你将能够使用批次中的最后一个文档作为下一个批次的光标的开始。

要解决此分页问题,​​请查看我在这篇文章中的回答,其中我已逐步解释了如何从Cloud Firestore数据库中以较小的块加载数据并将其显示ListView在按钮上。

解:

要从Firestore数据库获取数据并在中以较小的块显示它们RecyclerView,请按照以下步骤操作。

让我们以上面使用产品的示例为例。你可以使用产品,城市或任何你想要的东西。原理是相同的。假设你要在用户滚动时加载更多产品,我将使用RecyclerView.OnScrollListener

首先定义RecyclerView,将布局管理器设置为LinearLayoutManager并创建一个列表。我们还使用空列表实例化适配器并将适配器设置为我们的RecyclerView

RecyclerView recyclerView = findViewById(R.id.recycler_view);

recyclerView.setLayoutManager(new LinearLayoutManager(this));

List<ProductModel> list = new ArrayList<>();

ProductAdapter productAdapter = new ProductAdapter(list);

recyclerView.setAdapter(productAdapter);

假设我们有一个如下所示的数据库结构:

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;}

}

适配器类应如下所示:

private class ProductAdapter extends RecyclerView.Adapter<ProductViewHolder> {

private List<ProductModel> list;

ProductAdapter(List<ProductModel> list) {

this.list = list;

}

@NonNull

@Override

public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_product, parent, false);

return new ProductViewHolder(view);

}

@Override

public void onBindViewHolder(@NonNull ProductViewHolder productViewHolder, int position) {

String productName = list.get(position).getProductName();

productViewHolder.setProductName(productName);

}

@Override

public int getItemCount() {

return list.size();

}

}

该item_product布局只包含一个观点,一个TextView。

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/text_view"

android:textSize="25sp"/>

这是holder类的外观:

private class ProductViewHolder extends RecyclerView.ViewHolder {

private View view;

ProductViewHolder(View itemView) {

super(itemView);

view = itemView;

}

void setProductName(String productName) {

TextView textView = view.findViewById(R.id.text_view);

textView.setText(productName);

}

}

现在,让我们将限制定义为全局变量并将其设置为15。

private int limit = 15;

现在使用此限制定义查询:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();

CollectionReference productsRef = rootRef.collection("products");

Query query = productsRef.orderBy("productName", Query.Direction.ASCENDING).limit(limit);

以下代码也可以解决你的问题:

query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {

@Override

public void onComplete(@NonNull Task<QuerySnapshot> task) {

if (task.isSuccessful()) {

for (DocumentSnapshot document : task.getResult()) {

ProductModel productModel = document.toObject(ProductModel.class);

list.add(productModel);

}

productAdapter.notifyDataSetChanged();

lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {

@Override

public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

super.onScrollStateChanged(recyclerView, newState);

if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {

isScrolling = true;

}

}

@Override

public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

super.onScrolled(recyclerView, dx, dy);

LinearLayoutManager linearLayoutManager = ((LinearLayoutManager) recyclerView.getLayoutManager());

int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();

int visibleItemCount = linearLayoutManager.getChildCount();

int totalItemCount = linearLayoutManager.getItemCount();

if (isScrolling && (firstVisibleItemPosition + visibleItemCount == totalItemCount) && !isLastItemReached) {

isScrolling = false;

Query nextQuery = productsRef.orderBy("productName", Query.Direction.ASCENDING).startAfter(lastVisible).limit(limit);

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);

}

productAdapter.notifyDataSetChanged();

lastVisible = t.getResult().getDocuments().get(t.getResult().size() - 1);

if (t.getResult().size() < limit) {

isLastItemReached = true;

}

}

}

});

}

}

};

recyclerView.addOnScrollListener(onScrollListener);

}

}

});

其中lastVisible是一个DocumentSnapshot对象,代表查询中的最后一个可见项目。在这种情况下,每第15个被声明为全局变量:

private DocumentSnapshot lastVisible;

并且isScrollingisLastItemReached也是全局变量,并且声明为:

private boolean isScrolling = false;

private boolean isLastItemReached = false;

以上是 如何使用Android对Firestore进行分页? 的全部内容, 来源链接: utcz.com/qa/406953.html

回到顶部