使用本教程(由 Fazel 提到):
https ://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd
我创建了一个适合我的解决方案。我不知道这是否是正确的方法,也许有人可以改进这个答案。
onItemMove() 和 onMoved() 都被调用,而我仍在拖动项目。clearView() 只被调用一次。当我使用 Firestore 作为我的数据库时,我真的只想在拖动完成后更新项目。
我正在更新类别,所以我有一个扩展 FirestoreAdapter 的 CategoryFirestoreAdapter。我保存在数据库中的排序顺序从 1(不是 0)开始。
ItemTouchHelperAdapter
public interface ItemTouchHelperAdapter {
boolean onItemMove(int fromPosition, int toPosition);
void onItemDismiss(int position);
void clearView(); //added this
}
SimpleItemTouchHelperCallback
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setAlpha(ALPHA_FULL);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemClear();
}
mAdapter.clearView(); //add this so the method gets called in the CategoryFirestoreAdapter
}
类别FirestoreAdapter
public class CategoryFirestoreAdapter
extends FirestoreAdapter<CategoryFirestoreAdapter.ViewHolder>
implements ItemTouchHelperAdapter {
@Override
public void clearView() {
//Update the database here for the items that have moved.
FirebaseFirestore db = FirebaseFirestore.getInstance();
ArrayList<DocumentSnapshot> snapshots = getAllItems();
db.runTransaction(new Transaction.Function<Object>() {
@Nullable
@Override
public Object apply(@NonNull Transaction transaction) {
for (int i = 0; i < snapshots.size(); i++) {
DocumentSnapshot snapshot = snapshots.get(i);
DocumentReference docRef = db.collection("categories").document(snapshot.getId());
Category category = snapshot.toObject(Category.class);
Integer sortOrder = category.getSortOrder();
Integer newSortOrder = i+1;
if ((i + 1) != sortOrder) {
//only update items that have changed.
transaction.update(docRef, "sortOrder", newSortOrder); //sortOrder hardcoded - fix this
}
}
return null;
}
});
} ....
Firestore适配器
protected void onDocumentModified(DocumentChange change) {
// I changed this as it was moving things around again after updating the db.
// I am not sure why, and this may need improving, but this is working for me.
// Dont handle position changes, just updates.
// if (change.getOldIndex() == change.getNewIndex()) {
// // Item changed but remained in same position
// mSnapshots.set(change.getOldIndex(), change.getDocument());
// notifyItemChanged(change.getOldIndex());
// } else {
// // Item changed and changed position
mSnapshots.remove(change.getOldIndex());
mSnapshots.add(change.getNewIndex(), change.getDocument());
// notifyItemMoved(change.getOldIndex(), change.getNewIndex());
notifyItemChanged(change.getNewIndex()); //added
notifyItemChanged(change.getOldIndex()); //added
// }
}
protected ArrayList<DocumentSnapshot> getAllItems() {
return mSnapshots;
}