Как добавить 2 разных запроса в FirestoreRecyclerAdapter? - PullRequest
0 голосов
/ 29 мая 2018

У меня есть два запроса:

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 элементов.Теперь, когда я нажимаю кнопку, элементы из второго запроса переопределяют первые.

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

В итоге я использовал модифицированную версию класса адаптера из лабораторного примера кода Friendly-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() {}
}
0 голосов
/ 29 мая 2018

Нет ничего встроенного для объединения двух запросов в FirestoreRecyclerAdapter.

Лучшее, что я могу придумать, - это создание массива List / / комбинированных результатов в коде приложения, а затем использование адаптера массива.Это не идеально, так как вы не будете использовать FirebaseUI.

В качестве альтернативы, посмотрите на FirebaseUIs FirestorePagingAdapter, который объединяет несколько страниц (не в реальном времени) DocumentSnapshots водин вид переработчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...