2016-11-02 9 views
2

AndroidでFirebaseを使用してアプリケーションを構築しています。私のアプリケーションのシナリオは次のとおりです。次の画面を見てください。Android - FirebaseRecyclerAdapterを使用したクライアント側ソート

Transactions screen

あなたが見ることができるように、上記の画面では、私は、ユーザーの役割に基づいて、トランザクションのリストを表示しています:賃借人と所有者。また、ツールバーでは、次の画面に示すように、トランザクション状態を簡単にフィルタリングできます。

Transaction status filter

このシナリオを実現するために、私は次のような構造で、私のデータベースをモデル化しました:事がフラグメントのそれぞれで、私はちょうどorderByChildクエリを使用してきた、ある

- transactionsAll: 
    - transactionID1: 
     - orderDate: xxx 
     - role: Renter/Owner 
    - transactionID2: 
     .... 
- transactionsWaitingApproval: 
    - transactionID1: 
     - orderDate: xxx 
     - role: Renter/Owner 

それはそう

public void refreshRecyclerView(final String transactionStatus) { 
    Query transactionsQuery = getQuery(transactionStatus); 
    //Clean up old data 
    if (mFirebaseRecyclerAdapter != null) { 
     mFirebaseRecyclerAdapter.cleanup(); 
    } 

    mFirebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Transaction, TransactionViewHolder>(Transaction.class, R.layout.item_transaction, 
      TransactionViewHolder.class, transactionsQuery) { 

     @Override 
     public int getItemCount() { 
      int itemCount = super.getItemCount(); 

      if (itemCount == 0) { 
       mRecyclerView.setVisibility(View.GONE); 
       mEmptyView.setVisibility(View.VISIBLE); 
      } else { 
       mRecyclerView.setVisibility(View.VISIBLE); 
       mEmptyView.setVisibility(View.GONE); 
      } 

      return itemCount; 
     } 

     @Override 
     protected void populateViewHolder(final TransactionViewHolder viewHolder, final Transaction transaction, final int position) { 

      final CardView cardView = (CardView) viewHolder.itemView.findViewById(R.id.transactionCardView); 
      cardView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 

       } 
      }); 

      viewHolder.bindToPost(getActivity(), transaction, new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
       } 
      }); 
     } 
    }; 

    mRecyclerView.setAdapter(mFirebaseRecyclerAdapter); 
    mFirebaseRecyclerAdapter.notifyDataSetChanged(); 
} 

GEのように、賃借人または所有者かどうか、フラグメントの各ユーザーの役割に基づいて、トランザクションのリストを表示するにはTQueryの方法は次のとおりです、上記のクエリで

private Query getQuery(String transactionStatus) { 

    Query transactionsQuery = null; 
    int sectionNumber = getArguments().getInt(SECTION_NUMBER); 
    if (sectionNumber == 0) { // Renter fragment 
     if (transactionStatus == null || transactionStatus.equals(MyConstants.TransactionStatusConstants.allTransactionsValue)) 
      transactionsQuery = FirebaseDatabaseHelper.getTransactionsAllReference().orderByChild("productRenter").equalTo(UserHelper.getCurrentUser().getUid()); 
     else if (transactionStatus.equals(MyConstants.TransactionStatusConstants.waitingApprovalValue)) 
      transactionsQuery = FirebaseDatabaseHelper.getTransactionsWaitingApprovalReference().orderByChild("productRenter").equalTo(UserHelper.getCurrentUser().getUid()); 
     ... 

    } 
    if (sectionNumber == 1) { // Owner fragment 
     if (transactionStatus == null || transactionStatus.equals(MyConstants.TransactionStatusConstants.allTransactionsValue)) 
      transactionsQuery = FirebaseDatabaseHelper.getTransactionsAllReference().orderByChild("productOwner").equalTo(UserHelper.getCurrentUser().getUid()); 
     else if (transactionStatus.equals(MyConstants.TransactionStatusConstants.waitingApprovalValue)) 
      transactionsQuery = FirebaseDatabaseHelper.getTransactionsWaitingApprovalReference().orderByChild("productOwner").equalTo(UserHelper.getCurrentUser().getUid()); 
     ... 
    } 
    return transactionsQuery; 
} 

私は、クエリに別のorderByKey /子供/バリューを実行するためのオプションを使い果たしました。 docsに書かれているように、私はdouble orderByクエリを実行できません。

の注文方法は一度に1つしか使用できません。同じクエリで メソッドを複数回呼び出すと、エラーが発生します。

問題:データベースにプッシュすべての新しいトランザクションオブジェクトを使用すると、それはリサイクルビューの下部に表示されます。 orderDateプロパティに基づいてデータを降順でソートするにはどうすればよいですか?新しいトランザクションが最初のアイテムとしてリサイクル・ビューに表示されるようにしますか? same documentation page

、それと言われている。

がマルチユーザー アプリケーションのリストにデータを追加するためのプッシュ()メソッドを使用します。 push()メソッドは、新しい子が指定されたFirebaseリファレンスに追加されるたびに一意のキーを生成します。リスト内の新しい要素ごとにこれらの 自動生成キーを使用すると、複数のクライアント は、書き込みを行わずに同時に同じ場所に子を追加できます。 push()によって生成されたユニークキーは、タイムスタンプ に基づいているため、リスト項目は自動的にの順番でになります。

商品を注文したい年代順逆です。

Firebaseチームの誰かが、このシナリオを適切に達成する方法を提案してくれることを願っています。

+1

あなたの質問には、それを効率的に解析するために少しは進んでいます。しかし、あなたの質問がFirebaseUIアダプタの結果をどうやって元に戻すかということであれば、これは[より洗練された解決策の1つです](https://github.com/firebase/FirebaseUI-Android/issues/310#issuecomment-247816246) (しかし[これ](https://github.com/firebase/FirebaseUI-Android/issues/90)でも動作します) –

+0

うわー、それはアウト・オブ・ザ・ボックスの考えです!おかげでフランク! –

答えて

0

元々、私は作品にいくつかの追加のコンパレータがあると思っていましたが、フランクの答えが正しい方向に導かれました。

パーフランクさんのコメントは、上記のは、これらの2つのトリックは私のために働い

オーバーライドがFirebaseRecyclerAdapter内部のgetItemメソッドは次のように

@Override 
public User getItem(int position) { 
     return super.getItem(getItemCount() - 1 - position); 
} 

しかし、私は最終的には次のようにLinearLayoutManagerの設定と一緒に行きました:

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); 
linearLayoutManager.setStackFromEnd(true); 
linearLayoutManager.setReverseLayout(true); 
mRecyclerView.setLayoutManager(linearLayoutManager); 

この解決策は私の問題を解決しますが、Firebaseライブラリにdaの機能強化が追加されることを願っています操作。

+0

ユーザーが特定の時間に特定のオブジェクトをどのように表示するのか疑問に思うと、あなたは依然として制約されていることがわかります。項目を並べ替えて並べ替えるためのオーバーライドメソッドが必要です。 – Alexander

+0

2番目のアプローチの問題は、新しいアイテムが追加されるときにRecyclerViewが自動的に上にスクロールしないことです。 –

関連する問題