Android-使用FirebaseRecyclerAdapter进行客户端排序 [英] Android - Client-side sorting with FirebaseRecyclerAdapter

查看:59
本文介绍了Android-使用FirebaseRecyclerAdapter进行客户端排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building an application with Firebase on Android. The scenario for my application is as follows. Look at the following screen.

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

As you can see, in the above screen, I'm displaying a list of transactions based on the user role: Renter and Owner. Also, at the toolbar, user can easily filter any transaction statuses, shown in the following screen.

为实现此方案,我使用以下结构对数据库建模:

To achieve this scenario, I've modeled my database with the following structure:

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

问题是,在每个Fragment中,我都使用了orderByChild查询来显示基于每个片段中用户角色的交易列表,无论是Renter还是Owner,就像这样

The thing is, in each of the Fragment, I've used an orderByChild query just to display the list of transactions based on the user role in each of the fragment, whether it's the Renter or the Owner, like so

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方法如下:

Where the getQuery method is as follows:

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 所述,我无法执行双重查询.

With the above query, I've ran out of options to perform another orderByKey/Child/Value on the query. As written in the docs, I can't perform a double orderBy query.

您一次只能使用一种订购方式.致电订购 同一查询中多次使用此方法会引发错误.

You can only use one order-by method at a time. Calling an order-by method multiple times in the same query throws an error.

问题:将每个新的Transaction对象推送到数据库后,该对象显示在回收者视图的底部.如何基于orderDate属性对数据进行降序排序?这样,每笔新交易都将在回收者视图中显示为第一项?

The problem: With every new Transaction object pushed to the database, it is shown on the bottom of the recycler view. How can I sort the data based on the orderDate property, in descending order? So that every new transaction will be shown as the first item the recycler view?

相同的文档页面中, :

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

Use the push() method to append data to a list in multiuser applications. The push() method generates a unique key every time a new child is added to the specified Firebase reference. By using these auto-generated keys for each new element in the list, several clients can add children to the same location at the same time without write conflicts. The unique key generated by push() is based on a timestamp, so list items are automatically ordered chronologically.

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

I want the items to be ordered chronologically-reversed.

希望来自Firebase团队的人可以给我一些有关如何优雅实现此方案的建议.

Hopefully someone from the Firebase team can provide me with a suggestion on how to achieve this scenario gracefully.

推荐答案

本来我原以为作品中还会有其他比较器,但事实证明,弗兰克的回答使我朝着正确的方向前进.

Originally, I was thinking there would be some additional Comparators in the works, but it turns out Frank's answer led me to the right direction.

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

Per Frank's comment above, these two tricks worked for me:

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

Override the getItem method inside the FirebaseRecyclerAdapter as follows:

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

但是我终于按照以下步骤设置LinearLayoutManager:

But I finally went with setting the LinearLayoutManager as follows:

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

尽管此解决方案确实解决了我的问题,但希望Firebase库中会有更多的增强功能来进行数据处理.

Although this solution does solve my problem, hopefully there will be more enhancements coming to the Firebase library for data manipulation.

这篇关于Android-使用FirebaseRecyclerAdapter进行客户端排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆