Android 如何在FirestoreRecyclerAdapter中添加2个不同的查询?
我有两个问题:Android 如何在FirestoreRecyclerAdapter中添加2个不同的查询?,android,firebase,firebase-realtime-database,android-recyclerview,google-cloud-firestore,Android,Firebase,Firebase Realtime Database,Android Recyclerview,Google Cloud Firestore,我有两个问题: Query firstQuery = ref.orderBy("name", Query.Direction.ASCENDING).limit(10); getData(firstQuery); Query secondQuery = ref.orderBy("price", Query.Direction.ASCENDING).limit(10); getMoreData(secondQuery); 第一种方法如下所示: private void getData(Query
Query firstQuery = ref.orderBy("name", Query.Direction.ASCENDING).limit(10);
getData(firstQuery);
Query secondQuery = ref.orderBy("price", Query.Direction.ASCENDING).limit(10);
getMoreData(secondQuery);
第一种方法如下所示:
private void getData(Query query) {
firestoreRecyclerOptions = new FirestoreRecyclerOptions.Builder<ModelClass>().setQuery(query, ModelClass.class).build();
myFirestoreRecyclerAdapter = new MyFirestoreRecyclerAdapter(firestoreRecyclerOptions);
recyclerView.setAdapter(myFirestoreRecyclerAdapter);
}
private void getData(查询){
firestoreRecyclerOptions=新建firestoreRecyclerOptions.Builder().setQuery(查询,ModelClass.class.build();
myFirestoreRecyclerAdapter=新的myFirestoreRecyclerAdapter(firestoreRecyclerOptions);
设置适配器(myFirestoreRecyclerAdapter);
}
这是第二种方法
private void getMoreData(Query query) {
firestoreRecyclerOptions = new FirestoreRecyclerOptions.Builder<ModelClass>().setQuery(query, ModelClass.class).build();
myFirestoreRecyclerAdapter = new MyFirestoreRecyclerAdapter(firestoreRecyclerOptions);
recyclerView.setAdapter(myFirestoreRecyclerAdapter);
}
private void getMoreData(查询){
firestoreRecyclerOptions=新建firestoreRecyclerOptions.Builder().setQuery(查询,ModelClass.class.build();
myFirestoreRecyclerAdapter=新的myFirestoreRecyclerAdapter(firestoreRecyclerOptions);
设置适配器(myFirestoreRecyclerAdapter);
}
这两个变量都声明为全局变量:
private FirestoreRecyclerOptions<ModelClass> firestoreRecyclerOptions;
private MyFirestoreRecyclerAdapter myFirestoreRecyclerAdapter;
私有FirestoreRecyclerOptions FirestoreRecyclerOptions;
私人MyFirestoreRecyclerAdapter MyFirestoreRecyclerAdapter;
当应用程序启动时,元素将使用第一种方法显示在
RecyclerView
中。我想要实现的是,当触发getMoreData()
方法在同一适配器中添加第二个查询的结果时,单击一个按钮,就会得到20个元素。现在,当我单击该按钮时,第二个查询中的元素将覆盖第一个查询。在一个FirestoreRecyclerAdapter中没有内置的东西可以组合两个查询
我能想到的最好办法是在应用程序代码中创建一个组合结果的列表
/数组,然后使用数组适配器。这并不理想,因为您不会使用FirebaseUI
或者,看一看,它在单个回收器视图中组合了多页(非实时)DocumentSnapshots
。在FirestoreRecyclerAdapter
中没有内置功能来组合两个查询
我能想到的最好办法是在应用程序代码中创建一个组合结果的列表
/数组,然后使用数组适配器。这并不理想,因为您不会使用FirebaseUI
或者,看一看,它将(非实时)文档快照的多个页面组合在一个回收器视图中。我最终使用了
下面的类允许您添加初始查询,然后使用FirestoreAdapter.setQuery(query)
方法设置另一个查询
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.firestore.*
import com.google.firebase.firestore.EventListener
import java.util.*
/**
* RecyclerView adapter for displaying the results of a Firestore [Query].
*
* Note that this class forgoes some efficiency to gain simplicity. For example, the result of
* [DocumentSnapshot.toObject] is not cached so the same object may be deserialized
* many times as the user scrolls.
*
*
* See the adapter classes in FirebaseUI (https://github.com/firebase/FirebaseUI-Android/tree/master/firestore) for a
* more efficient implementation of a Firestore RecyclerView Adapter.
*/
abstract class FirestoreAdapter<VH : RecyclerView.ViewHolder>(private var query: Query,
private val lifecycleOwner: LifecycleOwner)
: RecyclerView.Adapter<VH>(), EventListener<QuerySnapshot>, LifecycleObserver {
private var listener: ListenerRegistration? = null
private val snapshots = ArrayList<DocumentSnapshot>()
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun startListening() {
if (listener == null) {
listener = query.addSnapshotListener(this)
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stopListening() {
listener?.apply {
remove()
listener = null
}
snapshots.clear()
notifyDataSetChanged()
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
internal fun cleanup(source: LifecycleOwner) {
source.lifecycle.removeObserver(this)
}
override fun onEvent(snapshot: QuerySnapshot?, error: FirebaseFirestoreException?) {
when {
error != null -> onError(error)
else -> {
// Dispatch the event
snapshot?.apply {
for (change in documentChanges) {
when (change.type) {
DocumentChange.Type.ADDED -> onDocumentAdded(change)
DocumentChange.Type.MODIFIED -> onDocumentModified(change)
DocumentChange.Type.REMOVED -> onDocumentRemoved(change)
}
}
onDataChanged()
}
}
}
}
protected fun onDocumentAdded(change: DocumentChange) {
snapshots.add(change.newIndex, change.document)
notifyItemInserted(change.newIndex)
}
protected fun onDocumentModified(change: DocumentChange) {
if (change.oldIndex == change.newIndex) {
// Item changed but remained in same position
snapshots[change.oldIndex] = change.document
notifyItemChanged(change.oldIndex)
} else {
// Item changed and changed position
snapshots.removeAt(change.oldIndex)
snapshots.add(change.newIndex, change.document)
notifyItemMoved(change.oldIndex, change.newIndex)
}
}
protected fun onDocumentRemoved(change: DocumentChange) {
snapshots.removeAt(change.oldIndex)
notifyItemRemoved(change.oldIndex)
}
fun setQuery(query: Query) {
stopListening()
// Clear existing data
snapshots.clear()
notifyDataSetChanged()
// Listen to new query
this.query = query
startListening()
}
override fun getItemCount(): Int = snapshots.size
protected fun getSnapshot(index: Int): DocumentSnapshot = snapshots[index]
protected open fun onError(exception: FirebaseFirestoreException) {}
protected open fun onDataChanged() {}
}
导入androidx.lifecycle.lifecycle
导入androidx.lifecycle.LifecycleObserver
导入androidx.lifecycle.LifecycleOwner
导入androidx.lifecycle.OnliFeCycleeEvent
导入androidx.recyclerview.widget.recyclerview
导入com.google.firebase.firestore*
导入com.google.firebase.firestore.EventListener
导入java.util*
/**
*用于显示Firestore[查询]结果的RecyclerView适配器。
*
*注意,这个类放弃了一些效率以获得简单性。例如
*[DocumentSnapshot.toObject]未缓存,因此可能会反序列化同一对象
*在用户滚动时多次。
*
*
*请参阅FirebaseUI中的适配器类(https://github.com/firebase/FirebaseUI-Android/tree/master/firestore)暂时
*Firestore RecyclerView适配器的更高效实现。
*/
抽象类FirestoreAdapter(私有变量查询:query,
私有val生命周期所有者:生命周期所有者)
:RecyclerView.Adapter(),EventListener,LifecycleObserver{
私有变量侦听器:ListenerRegistration?=null
private val snapshots=ArrayList()
@onLiFeCycleeEvent(Lifecycle.Event.ON_START)
有趣的听{
if(侦听器==null){
listener=query.addSnapshotListener(此)
}
}
@onLiFeCycleeEvent(Lifecycle.Event.ON_STOP)
有趣的停止听{
侦听器?应用{
删除()
侦听器=null
}
快照。清除()
notifyDataSetChanged()
}
@onLiFeCycleeEvent(Lifecycle.Event.ON_销毁)
内部乐趣清理(来源:LifecycleOwner){
source.lifecycle.removeObserver(此)
}
覆盖fun OneEvent(快照:QuerySnapshot?,错误:FirebaseFirestoreException?){
什么时候{
错误!=null->onError(错误)
其他->{
//发送事件
快照?应用{
对于(文档更改中的更改){
何时(更改.type){
DocumentChange.Type.Add->onDocumentAdded(更改)
DocumentChange.Type.MODIFIED->onDocumentModified(更改)
DocumentChange.Type.REMOVED->onDocumentRemoved(更改)
}
}
onDataChanged()
}
}
}
}
已添加受保护的文档(更改:DocumentChange){
添加快照(change.newIndex,change.document)
notifyItemInserted(change.newIndex)
}
受保护的文档已修改(更改:DocumentChange){
if(change.oldIndex==change.newIndex){
//项目已更改,但仍处于相同位置
快照[change.oldIndex]=change.document
notifyItemChanged(change.oldIndex)
}否则{
//项目变更和变更位置
snapshots.removeAt(change.oldIndex)
添加快照(change.newIndex,change.document)
notifyItemMoved(change.oldIndex、change.newIndex)
}
}
已删除受保护的文档(更改:DocumentChange){
snapshots.removeAt(change.oldIndex)
notifyItemRemoved(change.oldIndex)
}
funsetquery(查询:query){
停止听
//清除现有数据
快照。清除()
notifyDataSetChanged()
//听新的查询
this.query=query
听
}
重写getItemCount():Int=snapshots.size
受保护的快照(索引:Int):DocumentSnapshot=快照[索引]
受保护的open fun onError(异常:FirebaseFirestoreException){}
受保护的开放数据已更改(){}
}
我最终使用了来自的适配器类的修改版本
福勒