Android - 使用FirebaseRecyclerAdapter进行客户端排序

时间:2016-11-02 10:36:16

标签: android firebase firebase-realtime-database firebaseui

我在Android上使用Firebase构建应用程序。我的应用程序的场景如下。请看以下屏幕。

Transactions screen

如您所见,在上面的屏幕中,我显示了基于用户角色的交易列表:租客和所有者。此外,在工具栏中,用户可以轻松过滤任何交易状态,如以下屏幕所示。

Transaction status filter

为了实现这种情况,我使用以下结构对我的数据库进行了建模:

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

问题是,在每个片段中,我使用了orderByChild查询只是为了根据每个片段中的用户角色显示事务列表,无论是Renter还是所有者,像这样

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();
}

getQuery方法如下:

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 / Child / Value的选项。正如docs所述,我无法执行双重订单查询。

  

您一次只能使用一个 order-by方法。拨打订单   多次在同一查询中抛出一个错误。

问题:将每个新的Transaction对象推送到数据库后,它会显示在回收站视图的底部。如何根据orderDate属性按降序对数据进行排序?这样每个新交易都会显示为回收者查看的第一个项目吗?

same documentation page中,据说:

  

使用push()方法将数据附加到多用户的列表中   应用。 push()方法每次生成一个唯一键   新子项将添加到指定的Firebase参考中。通过使用这些   为列表中的每个新元素自动生成的密钥,多个客户端   可以在不写入的情况下同时将子项添加到同一位置   冲突。 push()生成的唯一键基于时间戳,   所以列表项会自动排序按时间顺序

我希望订购商品按时间顺序颠倒

希望来自Firebase团队的人能够向我提供有关如何优雅地实现此方案的建议。

1 个答案:

答案 0 :(得分:4)

最初,我在考虑会有一些额外的比较器正在进行中,但事实证明弗兰克的回答让我朝着正确的方向前进。

Per Frank上面的评论,这两个技巧对我有用:

覆盖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库会有更多的增强功能用于数据操作。