Есть ли способ разбить запросы на страницы путем объединения курсоров запросов с помощью FirestoreRecyclerAdapter?
у меня есть запрос, который выглядит так:
Query first = ref.orderBy("name", Query.Direction.ASCENDING).limit(10);
вот как я отображаю данные в my 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
? Это вообще возможно?
2 ответов
как @FrankvanPuffelen уже ответил в более раннем вопрос вашего, вы не можете достичь этого, потому что в вашем случае вы должны передать 2 разных запроса (first
и second
) к одному адаптеру, что невозможно с помощью FirestoreRecyclerAdapter
. Вы можете использовать первый запрос или второй с одним экземпляром адаптера.
решением было бы создать два разных списка, содержащих результаты каждого запроса и объединить их. Тогда вы можете пройти полученный список к другому адаптеру, скажем ArrayAdapter
и затем отобразить результаты в ListView
или еще лучше RecyclerView
. Проблема в этом случае заключается в том, что вы не сможете использовать функции реального времени, которые FirestoreRecyclerAdapter
класс обеспечивает, но этот подход решит вашу проблему.
Edit:
в соответствии с вашим запросом из раздела комментариев, я дам вам пример о том, как разбить запрос на кнопку нажмите в самом простом способ, используя ListView
и ArrayAdapter
. Вы можете достичь того же самого, используя RecyclerView
при прокрутке вниз. Но чтобы все было просто, предположим, что у нас есть 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
объект, представляющий последний элемент visibile из запроса. В этом случае каждый третий и объявляется как переменная gloabl:
private DocumentSnapshot lastVisible;
Edit2: здесь у вас также есть решение о том, как вы можно получить данные из базы данных Firestore и отображать их в меньших кусках в RecyclerView
когда пользователь прокручивает.
возможный подход-сохранить клавиши push каждого элемента в отдельном узле.
затем извлеките все ключи из этого узла в список массивов или что-то еще ..
затем на основе вашего номера разбиения на страницы извлеките ключи из этого списка массивов и используйте orderByKey Query и startAt и LimitToFirst запросы в сочетании, чтобы сделать алгоритм разбиения на страницы