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

前端之家收集整理的这篇文章主要介绍了如何使用Android对Firestore进行分页?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我阅读了Firestore文档和互联网上的所有文章(stackoverflow)关于Firestore分页但没有运气.我试图在docs中实现确切的代码,但没有任何反应.我有一个基本的数据库项目(超过1250或更多),我想逐步得到它们.通过滚动来加载15个项目(到数据库中的最后一项).

如果使用docs代码

  1. // Construct query for first 25 cities,ordered by population
  2. Query first = db.collection("cities")
  3. .orderBy("population")
  4. .limit(25);
  5.  
  6. first.get()
  7. .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
  8. @Override
  9. public void onSuccess(QuerySnapshot documentSnapshots) {
  10. // ...
  11.  
  12. // Get the last visible document
  13. DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
  14. .get(documentSnapshots.size() -1);
  15.  
  16. // Construct a new query starting at this document,// get the next 25 cities.
  17. Query next = db.collection("cities")
  18. .orderBy("population")
  19. .startAfter(lastVisible)
  20. .limit(25);
  21.  
  22. // Use the query for pagination
  23. // ...
  24. }
  25. });

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

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

解决方法

正如 official documentation中提到的,解决这个问题的关键是使用 startAfter()方法.因此,您可以通过将查询游标与limit()方法相结合来对查询进行分页.您将能够将批处理中的最后一个文档用作下一批的游标的开头.

解决这个分页问题,​​请参阅我在post中的回答,其中我已逐步解释了如何从较小的块中加载Cloud Firestore数据库中的数据,并在按钮单击时将其显示在ListView中.

解:

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

我们来看上面使用过产品的例子.您可以使用产品,城市或任何您想要的东西.原则是一样的.假设您想在用户滚动时加载更多产品,我将使用RecyclerView.OnScrollListener.

让我们首先定义RecyclerView并设置布局管理器:

  1. RecyclerView recyclerView = findViewById(R.id.recycler_view);
  2. recyclerView.setLayoutManager(new LinearLayoutManager(this));

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

  1. Firestore-root
  2. |
  3. --- products (collection)
  4. |
  5. --- productId (document)
  6. |
  7. --- productName: "Product Name"

一个看起来像这样的模型类:

  1. public class ProductModel {
  2. private String productName;
  3.  
  4. public ProductModel() {}
  5.  
  6. public ProductModel(String productName) {this.productName = productName;}
  7.  
  8. public String getProductName() {return productName;}
  9. }

这个适配器类应该是这样的:

  1. private class ProductAdapter extends RecyclerView.Adapter<ProductViewHolder> {
  2. private List<ProductModel> list;
  3.  
  4. ProductAdapter(List<ProductModel> list) {
  5. this.list = list;
  6. }
  7.  
  8. @NonNull
  9. @Override
  10. public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
  11. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_product,parent,false);
  12. return new ProductViewHolder(view);
  13. }
  14.  
  15. @Override
  16. public void onBindViewHolder(@NonNull ProductViewHolder productViewHolder,int position) {
  17. String productName = list.get(position).getProductName();
  18. productViewHolder.setProductName(productName);
  19. }
  20.  
  21. @Override
  22. public int getItemCount() {
  23. return list.size();
  24. }
  25. }

item_product布局仅包含一个视图,即TextView.

  1. <TextView
  2. android:layout_width="wrap_content"
  3. android:layout_height="wrap_content"
  4. android:id="@+id/text_view"
  5. android:textSize="25sp"/>

这就是持有者类应该是这样的:

  1. private class ProductViewHolder extends RecyclerView.ViewHolder {
  2. private View view;
  3.  
  4. ProductViewHolder(View itemView) {
  5. super(itemView);
  6. view = itemView;
  7. }
  8.  
  9. void setProductName(String productName) {
  10. TextView textView = view.findViewById(R.id.text_view);
  11. textView.setText(productName);
  12. }
  13. }

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

  1. private int limit = 15;

现在让我们使用这个限制来定义查询

  1. FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
  2. CollectionReference productsRef = rootRef.collection("products");
  3. Query firstQuery = productsRef.orderBy("productName",Query.Direction.ASCENDING).limit(limit);

以下是在您的案例中也具有魔力的代码

  1. query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
  2. @Override
  3. public void onComplete(@NonNull Task<QuerySnapshot> task) {
  4. if (task.isSuccessful()) {
  5. List<ProductModel> list = new ArrayList<>();
  6. for (DocumentSnapshot document : task.getResult()) {
  7. ProductModel productModel = document.toObject(ProductModel.class);
  8. list.add(productModel);
  9. }
  10. ProductAdapter productAdapter = new ProductAdapter(list);
  11. recyclerView.setAdapter(productAdapter);
  12. lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);
  13.  
  14. RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
  15. @Override
  16. public void onScrollStateChanged(RecyclerView recyclerView,int newState) {
  17. super.onScrollStateChanged(recyclerView,newState);
  18. if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
  19. isScrolling = true;
  20. }
  21. }
  22.  
  23. @Override
  24. public void onScrolled(RecyclerView recyclerView,int dx,int dy) {
  25. super.onScrolled(recyclerView,dx,dy);
  26.  
  27. LinearLayoutManager linearLayoutManager = ((LinearLayoutManager) recyclerView.getLayoutManager());
  28. int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
  29. int visibleItemCount = linearLayoutManager.getChildCount();
  30. int totalItemCount = linearLayoutManager.getItemCount();
  31.  
  32. if (isScrolling && (firstVisibleItemPosition + visibleItemCount == totalItemCount) && !isLastItemReached) {
  33. isScrolling = false;
  34. Query nextQuery = productsRef.orderBy("productName",Query.Direction.ASCENDING).startAfter(lastVisible).limit(limit);
  35. nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
  36. @Override
  37. public void onComplete(@NonNull Task<QuerySnapshot> t) {
  38. if (t.isSuccessful()) {
  39. for (DocumentSnapshot d : t.getResult()) {
  40. ProductModel productModel = d.toObject(ProductModel.class);
  41. list.add(productModel);
  42. }
  43. productAdapter.notifyDataSetChanged();
  44. lastVisible = t.getResult().getDocuments().get(t.getResult().size() - 1);
  45.  
  46. if (t.getResult().size() < limit) {
  47. isLastItemReached = true;
  48. }
  49. }
  50. }
  51. });
  52. }
  53. }
  54. };
  55. recyclerView.addOnScrollListener(onScrollListener);
  56. }
  57. }
  58. });

其中lastVisible是DocumentSnapshot对象,它表示查询中的最后一个visibile项.在这种情况下,每15个一个,它被声明为gloabl变量:

  1. private DocumentSnapshot lastVisible;

isScrolling和isLastItemReached也是全局变量,声明为:

  1. private boolean isScrolling = false;
  2. private boolean isLastItemReached = false;

猜你在找的Android相关文章