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

Nic*_*Lie 3 android firebase firebase-realtime-database firebaseui

我正在 Android 上使用 Firebase 构建应用程序。我的应用场景如下。看下面的画面。

交易画面

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

交易状态过滤器

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

- transactionsAll:
    - transactionID1:
        - orderDate: xxx
        - role: Renter / Owner
    - transactionID2:
        ....
- transactionsWaitingApproval:
    - transactionID1:
        - orderDate: xxx
        - role: Renter / Owner
Run Code Online (Sandbox Code Playgroud)

问题是,在每个 Fragment 中,我使用 orderByChild 查询只是为了根据每个 Fragment 中的用户角色显示交易列表,无论是 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();
}
Run Code Online (Sandbox Code Playgroud)

其中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;
}
Run Code Online (Sandbox Code Playgroud)

通过上面的查询,我已经用尽了对查询执行另一个 orderByKey/Child/Value 的选项。正如文档中所写,我无法执行双重 orderBy 查询。

您一次只能使用一种排序方式。在同一查询中多次调用 order-by 方法会引发错误。

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

同一个文档页面中,据说:

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

我希望物品按时间顺序颠倒排序。

希望 Firebase 团队的某个人可以为我提供有关如何优雅地实现此场景的建议。

Nic*_*Lie 7

最初,我认为工作中会有一些额外的比较器,但事实证明弗兰克的回答将我引向了正确的方向。

根据上面弗兰克的评论,这两个技巧对我有用:

重写 FirebaseRecyclerAdapter 中的 getItem 方法,如下所示:

@Override
public User getItem(int position) {
        return super.getItem(getItemCount() - 1 - position);
}
Run Code Online (Sandbox Code Playgroud)

但我最终设置了 LinearLayoutManager 如下:

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
linearLayoutManager.setStackFromEnd(true);
linearLayoutManager.setReverseLayout(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
Run Code Online (Sandbox Code Playgroud)

虽然这个解决方案确实解决了我的问题,但希望 Firebase 库能够进行更多的数据操作增强。