Android - 使用 FirebaseRecyclerAdapter 进行客户端排序
Android - Client-side sorting with FirebaseRecyclerAdapter
我正在 Android 上使用 Firebase 构建应用程序。我的应用程序的场景如下。看下面的画面。
如您所见,在上面的屏幕中,我显示了一个基于用户角色的 t运行操作列表:Renter 和 Owner。此外,在工具栏上,用户可以轻松过滤任何 t运行 操作状态,如以下屏幕所示。
为了实现这种情况,我使用以下结构对数据库进行了建模:
- transactionsAll:
- transactionID1:
- orderDate: xxx
- role: Renter / Owner
- transactionID2:
....
- transactionsWaitingApproval:
- transactionID1:
- orderDate: xxx
- role: Renter / Owner
问题是,在每个片段中,我都使用了 orderByChild 查询来显示基于每个片段中的用户角色的 t运行saction 列表,无论是 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 中所写,我无法执行双重 orderBy 查询。
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.
问题:随着每个新的 T运行saction 对象被推送到数据库,它显示在回收器视图的底部。如何根据 orderDate 属性 对数据进行降序排序?这样每个新的 t运行saction 都会显示为回收站视图的第一个项目?
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.
我要订购商品时间倒序。
希望 Firebase 团队的人可以为我提供有关如何优雅地实现此场景的建议。
最初,我以为作品中会有一些额外的比较器,但事实证明 Frank 的回答让我找到了正确的方向。
根据 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 库在数据操作方面会有更多增强功能。
我正在 Android 上使用 Firebase 构建应用程序。我的应用程序的场景如下。看下面的画面。
如您所见,在上面的屏幕中,我显示了一个基于用户角色的 t运行操作列表:Renter 和 Owner。此外,在工具栏上,用户可以轻松过滤任何 t运行 操作状态,如以下屏幕所示。
为了实现这种情况,我使用以下结构对数据库进行了建模:
- transactionsAll:
- transactionID1:
- orderDate: xxx
- role: Renter / Owner
- transactionID2:
....
- transactionsWaitingApproval:
- transactionID1:
- orderDate: xxx
- role: Renter / Owner
问题是,在每个片段中,我都使用了 orderByChild 查询来显示基于每个片段中的用户角色的 t运行saction 列表,无论是 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 中所写,我无法执行双重 orderBy 查询。
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.
问题:随着每个新的 T运行saction 对象被推送到数据库,它显示在回收器视图的底部。如何根据 orderDate 属性 对数据进行降序排序?这样每个新的 t运行saction 都会显示为回收站视图的第一个项目?
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.
我要订购商品时间倒序。
希望 Firebase 团队的人可以为我提供有关如何优雅地实现此场景的建议。
最初,我以为作品中会有一些额外的比较器,但事实证明 Frank 的回答让我找到了正确的方向。
根据 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 库在数据操作方面会有更多增强功能。