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>
Поэтому я показываю Загрузка ProgressBar до того, как RecyclerView заполняет его элементы. А что если на сервере нет ни одного элемента? В этой ситуации мой RecyclerView всегда пуст, а моя загрузка ProgressBar всегда видна пользователю.
Поэтому вместо отображения ProgressBar на неопределенный период времени я хочу показать пустой макет. Например, "Данные не найдены" или что-то подобное.
Окончательный результат должен быть следующим: ProgressBar должен отображаться до тех пор, пока данные не будут загружены в RecyclerView и после загрузки данных ProgressBar должен быть невидимым. Но если на сервере нет данных, вместо ProgressBar должна отображаться пустая схема.
В обычном RecyclerView у нас есть набор данных (некоторый ArrayList и т. Д.), И если он пуст, мы можем показать этот пустой макет. Но в случае FirebaseRecyclerAdapter у меня нет ссылки на снимок в моей активности или контексте. Также у меня нет никакого обратного вызова, который говорит мне, что на сервере нет данных.
Любой обходной путь очень поможет.
2 ответа
Вот что я бы попробовал. Сначала проверьте принятый ответ на вопрос, указанный ниже. Это дает очень хорошее представление о том, как работают запросы Firebase. Я считаю, что информация заслуживает доверия, так как ответ от кого-то из команды Firebase:
Как отделить начальную загрузку данных от инкрементных дочерних элементов с помощью Firebase?
Итак, основываясь на ответе на вопрос, связанный выше, и на том факте, что FirebaseRecyclerAdapter
поддерживается FirebaseArray
который заполняется с помощью ChildEventListener
Я бы добавил прослушиватель событий с одним значением в ту же ссылку на базу данных, которая использовалась для заполнения вашего 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);
адаптеры 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);
}