如何在firestorerecycleradapter中添加2个不同的查询?

oewdyzsn  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(323)

我有两个问题:

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个元素。现在,当我单击按钮时,第二个查询中的元素将覆盖第一个查询。

4smxwvx5

4smxwvx51#

我最终使用了友好eats代码实验室示例中的适配器类的修改版本。
下面的类允许您添加一个初始查询,然后使用 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() {}
}
ddarikpa

ddarikpa2#

没有内置的东西可以在一个数据库中组合两个查询 FirestoreRecyclerAdapter .
我能想到的最好办法就是创造一个 List /组合结果的数组出现在应用程序代码中,然后使用数组适配器。这并不理想,因为您不会使用firebaseui。
或者,看看firebaseuis FirestorePagingAdapter ,它组合了多个页面(非实时) DocumentSnapshots 在单个回收器视图中。

相关问题