拖放后如何在 RecyclerView 中存储项目位置

How to store items position in a RecyclerView after drag&drop

我有一个简单的待办事项列表应用程序,其中 RecyclerView/FirestoreRecyclerAdapter/ItemTouchHelper 包含项目 A、B、C、D(见附图)。现在我想有效地将​​这些项目的位置存储在 Firestore 中,最初是在我添加项目时以及我垂直拖放它们时。我如何从概念上或使用 existing/sample 代码来做到这一点。将它存储在云端很重要,这样即使我从另一台设备上查看它,项目位置也保持不变。

一些想法: 适配器位置 (int) 从 0 开始(在本例中为 D)。当我添加项目 E 时,它的适配器位置为 0,所有其他项目的位置都会改变。因此,每次添加新项目时,Firestore 中的存储位置可能会增加 1,并将显示在顶部。但是,如果我有成千上万的项目(例如在照片库应用程序中)怎么办?如果我每次拖放项目时更新所有项目的位置是否有效?

我想这应该是一个很常见的问题。

我的 Todo 应用程序的 MainActivity (https://i.stack.imgur.com/o3jJ1.jpg)

下面是方法 ItemTouchHelper.Callback onMoved():

的代码
@Override
        public void onMoved(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, int fromPos, @NonNull RecyclerView.ViewHolder target, int toPos, int x, int y) {
            super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);

            for (int maxItems = recyclerView.getChildCount(), i = 0; i < maxItems; ++i) {
                RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(recyclerView.getChildAt(i));
                int layoutPosition = holder.getLayoutPosition();
                int adapterPosition = holder.getAdapterPosition();
                TodoAdapter.TodoHolder h =  (TodoAdapter.TodoHolder)holder;
                String documentID = h.getDocumentID();
                TextView textViewTitle = (TextView)h.itemView.findViewById(R.id.todo_title);
                CharSequence title = textViewTitle.getText();

                DocumentReference docRef = mFirestore.collection("todos").document(documentID);
                docRef.update("position", adapterPosition);
            }
        }

Now I would like to effectivly store the position of these items in Firestore, initially when I add an item and when ever I vertically drag & drop them.

虽然这在技术上是可行的,但我认为 Firestore 不是解决此问题的最佳选择,因为 Firestore 中的所有内容都与读写次数有关。因此,每次更改项目的位置时,您将执行与剩余项目数相等的写入操作数。也试着看看 Firebase realtime database。两者配合得很好。

How can I do that conceptionally

只需为每个元素添加一个序号属性,代表在列表中的位置,然后根据属性对它们进行排序(升序或降序)。将元素从一个位置移动到另一个位置后,将每个剩余对象的位置更新一个。

It's important to store it in the cloud so the items position stay the same if I look a it from another device.

如果您让所有元素保持有序,那么每个用户都能看到相同的排列。

So the stored position in Firestore should probably increase by 1 each time a new item is added

对了,每增加一个项目,排名就会增加一位。

Is it effective if I update the position for all the items each time I drag & drop an item?

更新列表开头的项目的位置肯定会非常昂贵。让我们举个例子。假设您有一个包含 1000 个项目的集合,并且您想要添加一个新项目作为列表中的第二个项目。这意味着您需要为添加项目支付一次写入操作费用,再加上另外 999 次写入操作以更新剩余 999 个项目的位置。因此,您总共需要支付 1000 次写入操作的费用。这是否满足您的需求由您决定。