我阅读了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;
并且isScrolling
和isLastItemReached
也是全局变量,并且声明为:
private boolean isScrolling = false;
private boolean isLastItemReached = false;
怎么办?文档没有太多的细节。 PS:我需要与回收器视图(不是列表视图),当用户滚动。谢谢
问题内容: 我想使用itext生成pdf。我会在某些时候添加内容以进行分页。我需要插入几个单独的conenidos依赖源,所以我要求用户在单独的页面上插入。有任何想法吗??? 问题答案: 调用告诉iText将后续对象放置在新页面上。仅当您放置下一个对象时,才会真正创建新页面。另外,仅在当前页面不为空白时创建一个新页面;否则,仅创建一个新页面。否则,它将被忽略;您可以用来克服这一点。 请参见下面的链
我想用iText生成一个pdf。我会在某个时候添加内容以进行分页。我需要插入几个单独的conenidos依赖源,所以我要求用户在单独的页面上这样做。有什么想法吗???
问题内容: 使用以下代码显示我的Twitter个人资料中的朋友列表。我想一次只加载一个特定的数字,例如20,然后在底部为第1-2-3-4-5页的页面提供分页链接(但是,除以限制) **更新**** 这项工作有效,只需要抵消从开始的输出即可。在想什么? 问题答案: 一个非常优雅的解决方案是使用:
我正在编写一个Python脚本来从我的数码相机导入图片,并且我正在使用Pandas来帮助记账传入的图像。我正在使用EXIF数据为单个图像标记信息,例如相机型号、图像模式、图像格式和相机获取图像的时间戳。这些数据用于将图像分离到目录结构中。我正在努力解决的是如何使用Pandas根据一组时间戳对图像进行分组,例如,这些时间戳都在彼此相隔半小时之内。举个例子,假设我有六张照片,其中三张是在相隔9分钟内拍
最近我尝试使用ApacheFlink进行快速批处理。我有一个表,它有一个列:value和一个不相关的索引列 基本上我想计算每5行值的平均值和范围。然后我将根据我刚才计算的平均值计算平均值和标准偏差。所以我想最好的方法是使用窗口。 看起来是这样的 但是我不知道用。我试过,但它说没有这样的输入。我只希望它在从源代码读取时按顺序分组。但是它必须是一个时间属性,所以我不能使用索引列作为排序。 我是否必须添