FirebaseRecyclerAdapter с пустым представлением

Я знаю, что есть много способов иметь пустой вид для RecyclerView. Но мой вопрос касается FirebaseRecyclerView.

Мой макет:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:id="@+id/feed_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

<ProgressBar
    android:id="@+id/feed_loading"
    style="?android:attr/progressBarStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:visibility="gone"/>
</RelativeLayout>

Итак, я показываю Load ProgressBar, прежде чем RecyclerView заполнит его элементы. Теперь, что, если у сервера нет элемента. В этой ситуации мой RecyclerView всегда пуст, и моя загрузка ProgressBar всегда видна пользователю.

Итак, вместо того, чтобы показывать ProgressBar на неопределенный период, я хочу показать некоторый пустой макет. Например. "Нет данных" или что-то подобное.

Конечный результат должен быть: ProgressBar должен отображаться до тех пор, пока данные не будут загружены в RecyclerView, и как только данные будут загружены, ProgressBar должен быть невидим. Но если данных нет в сервере, вместо ProgressBar следует указывать пустую макет.

В обычном RecyclerView у нас есть набор данных (некоторые ArrayList и т.д.), и если он пуст, мы можем показать этот пустой макет. Но в случае FirebaseRecyclerAdapter у меня нет ссылки на Snapshot в моей деятельности или контексте. Также у меня нет обратного вызова, который говорит мне, что на сервере нет данных.

Любое обходное решение поможет много.

Ответ 1

Вот что я хотел бы попробовать. Сначала проверьте принятый ответ на вопрос, указанный ниже. Это дает очень хорошее представление о том, как работают запросы Firebase. Я считаю, что информация доверена, так как ответ от кого-то из команды Firebase:

Как отделить начальную загрузку данных от инкрементальных детей с помощью Firebase?

Итак, на основе ответа на вопрос, связанный выше, и того факта, что FirebaseRecyclerAdapter поддерживается FirebaseArray, который заполняется с помощью ChildEventListener, я бы добавил прослушиватель событий Single value в той же ссылке базы данных используется для заполнения вашего FirebaseRecyclerAdapter. Что-то вроде этого:

//create database reference that will be used for both the
//FirebaseRecyclerAdapter and the single value event listener
dbRef = FirebaseDatabase.getInstance().getReference();

//setup FirebaseRecyclerAdapter
mAdapter = new FirebaseRecyclerAdapter<Model, YourViewHolder>(
                Model.class, R.layout.your_layout, YourViewHolder.class, dbRef) {

                @Override
                public void populateViewHolder(YourViewHolder holder, Model model, int position){

                     //your code for populating each recycler view item

                };

mRecyclerView.setAdapter(mAdapter);

//add the listener for the single value event that will function
//like a completion listener for initial data load of the FirebaseRecyclerAdapter
dbRef.addListenerForSingleValueEvent(new ValueEventListener() {
             @Override
             public void onDataChange(DataSnapshot dataSnapshot) {
                 //onDataChange called so remove progress bar

                 //make a call to dataSnapshot.hasChildren() and based 
                 //on returned value show/hide empty view 

                 //use helper method to add an Observer to RecyclerView    
             }

             @Override
             public void onCancelled(DatabaseError databaseError) {

             }
      });

Это будет обрабатывать начальную настройку RecyclerView. Когда вызывающий onDataChange вызывается в однослужебном прослушителе событий, используйте вспомогательный метод для добавления наблюдателя в FirebaseRecyclerAdapter для обработки любых последующих добавлений/удалений в местоположение базы данных.

mObserver = new RecyclerView.AdapterDataObserver() {
            @Override
            public void onItemRangeInserted(int positionStart, int itemCount) {
                //perform check and show/hide empty view
            }

            @Override
            public void onItemRangeRemoved(int positionStart, int itemCount) {
                //perform check and show/hide empty view
            }
           };
mAdapter.registerAdapterDataObserver(mObserver);

Ответ 2

Ответа на этот вопрос fooobar.com/info/39106/...

Адаптеры FirebaseUI в настоящее время имеют метод onDataChanged(), который вы можете переопределить, чтобы определить, когда они будут загружены набор данных.

Смотрите исходный код в github. Оттуда:

Этот метод будет запускаться каждый раз, когда обновления из базы данных будут полностью обработаны. Поэтому при первом вызове этого метода загружаются исходные данные, включая случай, когда данные вообще отсутствуют. Каждый раз, когда вызывается метод, завершается полное обновление (потенциально состоящее из обновлений для нескольких дочерних элементов).

Обычно вы переопределяете этот метод, чтобы скрыть индикатор загрузки (после начальной загрузки) или завершить пакетное обновление элемента интерфейса.

Приложение примера FirebaseUI переопределяет onDataChanged(), чтобы скрыть свой индикатор загрузки:

public void onDataChanged() {
    // If there are no chat messages, show a view that invites the user to add a message.
    mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
}