如何在 FirestoreRecyclerAdapter 中添加 2 个不同的查询?
Posted
技术标签:
【中文标题】如何在 FirestoreRecyclerAdapter 中添加 2 个不同的查询?【英文标题】:How to add 2 different queries inside an FirestoreRecyclerAdapter? 【发布时间】:2018-11-08 12:00:52 【问题描述】:我有两个疑问:
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 getMoreData(Query query)
firestoreRecyclerOptions = new FirestoreRecyclerOptions.Builder<ModelClass>().setQuery(query, ModelClass.class).build();
myFirestoreRecyclerAdapter = new MyFirestoreRecyclerAdapter(firestoreRecyclerOptions);
recyclerView.setAdapter(myFirestoreRecyclerAdapter);
两个变量都声明为全局变量:
private FirestoreRecyclerOptions<ModelClass> firestoreRecyclerOptions;
private MyFirestoreRecyclerAdapter myFirestoreRecyclerAdapter;
当应用启动时,使用第一种方法将元素显示在RecyclerView
中。我想要实现的是,在单击按钮时,当触发 getMoreData()
方法以将第二个查询的结果添加到同一适配器中时,最终有 20 个元素。现在,当我单击按钮时,第二个查询中的元素将覆盖第一个。
【问题讨论】:
【参考方案1】:在FirestoreRecyclerAdapter
中组合两个查询没有任何内置功能。
我能想到的最好的方法是在您的应用代码中创建一个组合结果的List
/array,然后使用数组适配器。这并不理想,因为您不会使用 FirebaseUI。
或者,看看FirebaseUIs FirestorePagingAdapter
,它将(非实时)DocumentSnapshots
的多个页面组合在一个回收器视图中。
【讨论】:
我想我会找到组合这两个查询的可能性,因为它们都返回相同类型的对象。但现在知道你说了什么,我正试图找到另一种方法。还阅读this,我知道第二个选项也对我没有帮助。谢谢!【参考方案2】:我最终使用了来自Friendly-eats code lab sample 的适配器类的修改版本。
以下类允许您添加一个初始查询,然后使用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()
【讨论】:
以上是关于如何在 FirestoreRecyclerAdapter 中添加 2 个不同的查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?