2017-08-08 7 views
0

私は次のように簡略化することができ、非正規化データベースがあります。私はUIに表示する何2つのNested FirebaseIndexRecyclerAdapterがデータロードを完了したことを知る方法?

|__ menu 
|  |___ menuKey1 
|    |___ subMenus (key list of subMenus belongs to menu) 
|    |___ other fields... 
| 
|__ subMenu 
|  |___ subMenuKey1 
|    |__ menuItems (key list of menuItems belongs to subMenu) 
|    |__ other fields... 
| 
|__ menuItem 
     |_____ ... 

は、各メニュー項目の独自のリスト(1インナーを持つ、サブメニュー(外RecyclerView)のリストです外部RecyclerViewの各行のRecyclerView)。 「

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:visibility="gone"> 

    <TextView 
     android:id="@+id/submenu_name" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:textAllCaps="true" 
     android:textStyle="bold" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintTop_toTopOf="parent" /> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/submenu_menu_items" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:paddingBottom="8dp" 
     app:layoutManager="android.support.v7.widget.LinearLayoutManager" 
     app:layout_constraintBottom_toBottomOf="parent" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintTop_toBottomOf="@id/submenu_name" /> 

</android.support.constraint.ConstraintLayout> 

row_menu_item.xmlはちょうどので、私はドンTextViewsでのmenuItemの名前と価格を示しています。ここ

rootRef = FirebaseDatabase.getInstance().getReference(); 
DatabaseReference subMenuKeyRef = rootRef.child("menu").child(menuKey).child("subMenus"); 
DatabaseReference subMenuRef = rootRef.child("subMenu"); 
subMenuAdapter = new FirebaseIndexRecyclerAdapter<MySubMenu, SubMenuHolder>(
     MySubMenu.class, 
     R.layout.row_submenu, 
     SubMenuHolder.class, 
     subMenuKeyRef, 
     subMenuRef) { 
    @Override 
    protected void populateViewHolder(SubMenuHolder viewHolder, MySubMenu model, int position) { 
     String subMenuKey = getRef(position).getKey(); 
     DatabaseReference menuItemKeyRef = rootRef.child("subMenu").child(subMenuKey).child("menuItems"); 
     DatabaseReference menuItemRef = rootRef.child("menuItem"); 
     FirebaseIndexRecyclerAdapter menuItemAdapter = new FirebaseIndexRecyclerAdapter<MyMenuItem, MenuItemHolder>(
       MyMenuItem.class, 
       R.layout.row_menu_item, 
       MenuItemHolder.class, 
       menuItemKeyRef, 
       menuItemRef) { 
      @Override 
      protected void populateViewHolder(MenuItemHolder viewHolderx, MyMenuItem modelx, int positionx) { 
       viewHolderx.setName(modelx.getName()); 
       viewHolderx.setPrice(modelx.getPrice()); 
      } 
     }; 
     viewHolder.setName(model.getName()); 
     viewHolder.setMenuItemList(menuItemAdapter); 
    } 
}; 
subMenuList.setAdapter(subMenuAdapter); 

row_submenu.xmlで、外側RecyclerViewの行である:私は私のフラグメントのonCreate()に次のコードでこれを達成しましたそれをここに含めてください。

この設計では、RecyclerViewの初期化時に不思議なアニメーションやジャンプなどが発生します。私は2つの質問を持っています:

  • デザインの点でより良い選択肢がありますか? (ExpandableListViewと同等のもの)

  • もしそうでなければ、最初のデータロードが完了したことを検出して、最後のmenuItemが取得されるまですべてを隠すことができますか?私はaddListenerForSingleValueEventmenuItemRefに呼び出すとここではうまくいかないと思う。

答えて

0

2つのカウンタを使用して、非同期取得の終了を検出できるようにしました。キーカウントはtotalItemCountに累積的に加算され、内部アダプタの内部にロードされるアイテムの総数が保持されます。内部アダプタがViewHolderに入力すると、populatedItemCountは1つ増え、現在の値はtotalItemCountと比較されます。値が等しい場合は、すべてのデータが取得され、行内の親RecyclerViewおよびRecyclerViewが可視になることを意味します。私はまだ二つのカウンタを比較して、if文についてわからない

rootRef = FirebaseDatabase.getInstance().getReference(); 
DatabaseReference subMenuKeyRef = rootRef.child("menu").child(menuKey).child("subMenus"); 
DatabaseReference subMenuRef = rootRef.child("subMenu"); 
subMenuAdapter = new FirebaseIndexRecyclerAdapter<MySubMenu, SubMenuHolder>(
     MySubMenu.class, 
     R.layout.row_submenu, 
     SubMenuHolder.class, 
     subMenuKeyRef, 
     subMenuRef) { 
    int totalItemCount = 0; 
    int populatedItemCount = 0; 

    @Override 
    protected void populateViewHolder(SubMenuHolder viewHolder, MySubMenu model, int position) { 
     totalItemCount += model.getMenuItems().size(); 
     String subMenuKey = getRef(position).getKey(); 
     DatabaseReference menuItemKeyRef = rootRef.child("subMenu").child(subMenuKey).child("menuItems"); 
     DatabaseReference menuItemRef = rootRef.child("menuItem"); 
     FirebaseIndexRecyclerAdapter menuItemAdapter = new FirebaseIndexRecyclerAdapter<MyMenuItem, MenuItemHolder>(
       MyMenuItem.class, 
       R.layout.row_menu_item, 
       MenuItemHolder.class, 
       menuItemKeyRef, 
       menuItemRef) { 
      @Override 
      protected void populateViewHolder(MenuItemHolder viewHolderx, MyMenuItem modelx, int positionx) { 
       populatedMenuItemCount++; 
       viewHolderx.setName(modelx.getName()); 
       viewHolderx.setPrice(modelx.getPrice()); 

       // TODO - Find a resolution if this if never gets true 
       if (populatedMenuItemCount == totalMenuItemCount) { 
        (new Handler()).postDelayed(new Runnable() { 
         @Override 
         public void run() { 
          showSubMenuList(); 
         } 
        }, 500); 
       } 
      } 
     }; 
     viewHolder.setName(model.getName()); 
     viewHolder.setMenuItemList(menuItemAdapter); 
    } 
}; 
subMenuList.setAdapter(subMenuAdapter); 

は、ここで私は疑問に提供ネストされたアダプタの最後のバージョンです。何らかの理由でデータの取得が中断し、if文の条件が真にならず、アプリケーションがハングアップするケースがありますか?

0

FirebaseUIアダプタは、データの変更が完全に読み込まれたときに検出するonDataChanged()というメソッドを持っています。

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

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

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

参照:How to dismiss a progress bar even if there is no view to populate in the FirebaseListAdapter?この情報(およびサンプル)を更新しました。

+0

外部アダプターのデータロードが完了したときを知っています。しかし、各エントリは別の内部アダプタを作成します。最後の内部データロード完了がいつ発生するのかを知りたいのですが、それらのすべてが非同期であるためにできません。 – Mehmed

関連する問題