10

RecyclerViewに空のビューを表示する方法がたくさんあることは知っています。しかし、私の質問はFirebaseRecyclerViewです。空のビューを持つFirebaseRecyclerAdapter

私のレイアウトは次のとおりです。

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

RecyclerViewは、その項目を埋める前に、だから私はロードプログレスバーを表示しています。サーバーにアイテムがない場合はどうなりますか?この状況で私のRecyclerViewは常に空であり、私のLoading ProgressBarは常にユーザーに見えます。

したがって、ProgressBarを無期限に表示する代わりに、空のレイアウトをいくつか表示する必要があります。例えば。 「データが見つかりません」などのメッセージ。

最終結果は次のとおりです。ProgressBarは、データがRecyclerViewにロードされ、データがロードされるまで表示される必要があります。ProgressBarは不可視です。しかし、サーバーにデータが存在しない場合は、ProgressBarの代わりに空のレイアウトを表示する必要があります。

通常のRecyclerViewでは、データセット(ArrayListなど)があり、空の場合は空のレイアウトを表示できます。しかし、FirebaseRecyclerAdapterの場合、私は自分のアクティビティやコンテキストにスナップショットの参照を持っていません。また、サーバーにデータが存在しないことを示すコールバックはありません。

いずれの回避策も多大に役立ちます。

答えて

22

ここに私が試してみたいことがあります。まず、下にリンクされている質問への回答を確認してください。 Firebaseのクエリがどのように機能するかについての非常に良い洞察を提供します。答えはFirebaseチームの誰かであるので、私は、信頼できる情報を検討したい:

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

上にリンクされ、質問への答えと FirebaseRecyclerAdapterFirebaseArrayによって支えられているという事実に基づいたので

、どの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が呼び出された場合、helperメソッドを使用してオブザーバを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); 
+0

おかげで、その偉大なトリックをし、私のために働きました。 –

+0

問題ありません。喜んで助けてください。 –

+0

onItemRangeRemoved()が空のリストになったかどうかを確認できないようです。 AdapterDataObserverとdbRef.addValueEventListener()を呼び出すだけの違いは何ですか? –

0

回答から:https://stackoverflow.com/a/40204298/2170278

FirebaseUIアダプタは、今日あなたは彼らがデータのセットをロードし終わったときに検出するために、オーバーライドすることができonDataChanged()方法があります。

source code on githubを参照してください。そこから:

このメソッドは、データベースからの更新が完全に処理されるたびにトリガーされます。最初にこのメソッドが呼び出されると、データがまったく使用できない場合を含めて、初期データがロードされました。次にメソッドが呼び出されるたびに、完全な更新(複数の子アイテムへの更新からなる可能性があります)が完了しました。

ロードインジケータを非表示にしたり(最初のロード後に)、UI要素のバッチ更新を完了するには、通常このメソッドをオーバーライドします。

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); 
} 
関連する問題