10

Wiem, że istnieje wiele sposobów na uzyskanie pustego widoku na widok RecyclerView. Ale moje pytanie dotyczy FirebaseRecyclerView.FirebaseRecyclerAdapter z pustym widokiem

Mój układ jest:

<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> 

Więc pokazuję Loading ProgressBar przed RecyclerView wypełnia swoje pozycje. Teraz, jeśli serwer nie ma żadnego elementu. W tej sytuacji mój RecyclerView jest zawsze pusty i mój ProgressBar ładowania zawsze widoczny dla użytkownika.

Zamiast pokazywać ProgressBar na czas nieokreślony, chcę pokazać pusty układ. Na przykład. "Nie znaleziono danych" lub coś podobnego.

Końcowy wynik powinien wyglądać następująco: Pasek postępu powinien zostać wyświetlony, dopóki dane nie zostaną załadowane do okna RecyclerView, a po załadowaniu danych pasek postępu powinien być niewidoczny. Ale jeśli na serwerze nie ma żadnych danych, powinien zostać wyświetlony pusty układ zamiast ProgressBar.

W normalnym RecyclerView mamy zestaw danych (niektóre ArrayList, itp.) I jeśli jest pusty, możemy pokazać ten pusty układ. Ale w przypadku FirebaseRecyclerAdapter, nie mam odniesienia do Migawki w mojej Aktywności lub Kontekście. Nie mam też żadnego wywołania zwrotnego, które mówi mi, że żadne dane nie są obecne na serwerze.

Każde obejście bardzo pomoże.

Odpowiedz

22

Oto, co chciałbym wypróbować. Najpierw sprawdź zaakceptowaną odpowiedź na pytanie powiązane poniżej. Zapewnia bardzo dobry wgląd w działanie zapytań Firebase. Pomyślę info zaufany, ponieważ odpowiedź jest przez kogoś na Firebase drużynie:

How to separate initial data load from incremental children with Firebase?

Tak, na podstawie odpowiedzi na pytania związanego powyżej oraz fakt, że FirebaseRecyclerAdapter jest wspierany przez FirebaseArray który jest zapełniany przy użyciu ChildEventListener Dodałbym detektor zdarzeń o pojedynczej wartości na tym samym odwołaniu do bazy danych, który byłby używany do zapełniania twojego FirebaseRecyclerAdapter. Coś takiego:

//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) { 

      } 
     }); 

To obsłuży początkową konfigurację RecyclerView. Po wywołaniu onDataChange w detektorze zdarzeń o pojedynczej wartości należy użyć metody pomocniczej w celu dodania obserwatora do obiektu FirebaseRecyclerAdapter w celu obsługi kolejnych dodawania/usuwania do lokalizacji bazy danych.

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); 
+0

Dzięki za rozwiązanie, jego wielki podstęp i pracował dla mnie. –

+0

Nie ma problemu. Miło, że mogłem pomóc. –

+0

Nie mogę sprawdzić, czy funkcja onItemRangeRemoved() dała pustą listę. Jaka jest różnica między AdapterDataObserver a zwykłym wywołaniem dbRef.addValueEventListener()? –

0

Odpowiedź: https://stackoverflow.com/a/40204298/2170278

adaptery FirebaseUI w dzisiejszych czasach mieć metodę onDataChanged() że można przesłonić wykryć kiedy skończysz ładowania zestawu danych.

Zobacz source code on github. Stamtąd:

Ta metoda zostanie uruchomiona za każdym razem, gdy aktualizacje z bazy danych zostaną całkowicie przetworzone. Tak więc po raz pierwszy wywoływana jest ta metoda, załadowano dane początkowe - w tym przypadek, w którym żadne dane nie są dostępne. Przy następnym wywołaniu metody pełna aktualizacja (potencjalnie składająca się z aktualizacji wielu elementów potomnych) została zakończona.

Typowo można zastąpić tę metodę, aby ukryć wskaźnik ładowania (po początkowym załadowaniu) lub ukończyć aktualizację partii do elementu interfejsu użytkownika.

Próbka aplikacja FirebaseUI nadpisuje onDataChanged() ukryć swój wskaźnik „ładowanie”:

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); 
} 
Powiązane problemy