如何捕获与RecyclerView一起使用的ItemTouchHelper的Drop操作

RecyclerView的 ItemTouchHelper有问题。

我正在做一个游戏。 游戏板实际上是一个RecyclerView。 RecyclerView的GridLayoutManager有一些跨度数。 我想实现拖放 recyclerview的项目。 任何项目都可以拖动所有方向(上,下,左,右)。

private void initializeLayout() { recyclerView.setHasFixedSize(true); recyclerView.setLayoutFrozen(true); recyclerView.setNestedScrollingEnabled(false); // set layout manager GridLayoutManager layoutManager = new GridLayoutManager(getContext(), BOARD_SIZE, LinearLayoutManager.VERTICAL, true); recyclerView.setLayoutManager(layoutManager); // Extend the Callback class ItemTouchHelper.Callback itemTouchCallback = new ItemTouchHelper.Callback() { public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { Log.w(TAG, "onMove"); return false; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { // Application does not include swipe feature. } @Override public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) { Log.d(TAG, "onMoved"); // this is calling every time, but I need only when user dropped item, not after every onMove function. } @Override public boolean isItemViewSwipeEnabled() { return false; } @Override public boolean isLongPressDragEnabled() { return true; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END; int swipeFlags = 0; return makeMovementFlags(dragFlags, swipeFlags); } }; ItemTouchHelper touchHelper = new ItemTouchHelper(itemTouchCallback); touchHelper.attachToRecyclerView(recyclerView); } 

那么,为什么ItemTouchHelper的onMoved函数仍然在RecyclerView上拖动项目? 我怎样才能做到这一点?

Solutions Collecting From Web of "如何捕获与RecyclerView一起使用的ItemTouchHelper的Drop操作"

在一次“拖放”时,onMove()将被多次调用,但clearView()将被调用一次。 所以你可以用这个来表示拖动结束了(下降发生了)。 并使用dragFrom和dragTo两个variables来追踪完成的“拖放”中的真实位置。

 private ItemTouchHelper.Callback dragCallback = new ItemTouchHelper.Callback() { int dragFrom = -1; int dragTo = -1; @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT, 0); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); if(dragFrom == -1) { dragFrom = fromPosition; } dragTo = toPosition; adapter.onItemMove(fromPosition, toPosition); return true; } private void reallyMoved(int from, int to) { // I guessed this was what you want... } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { } @Override public boolean isLongPressDragEnabled() { return true; } @Override public boolean isItemViewSwipeEnabled() { return false; } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); if(dragFrom != -1 && dragTo != -1 && dragFrom != dragTo) { reallyMoved(dragFrom, dragTo); } dragFrom = dragTo = -1; } }; 

adapter.onItemMove(fromPosition,toPosition)如下所示:

list.add(toPosition, list.remove(fromPosition)); notifyItemMoved(fromPosition, toPosition);

onSelectedChanged(RecyclerView.ViewHolder, int)callback提供有关当前actionState的信息:
ACTION_STATE_IDLE
ACTION_STATE_DRAG
ACTION_STATE_SWIPE

所以你可以跟踪订单是否改变,当状态改变为ACTION_STATE_IDLE ,你可以做你需要做的事情!

例:

 private final class MyCallback extends ItemTouchHelper.Callback { private boolean mOrderChanged; @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { // Check if positions of viewHolders correspond to underlying model, and if not, flip the items in the model and set the mOrderChanged flag mOrderChanged = true; } @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if (actionState == ItemTouchHelper.ACTION_STATE_IDLE && mOrderChanged) { doSomething(); mOrderChanged = false; } } 

你必须在你的适配器中实现OnMove监听器:

Collections.swap(youCoolList, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition);

像这个人做https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.blviq6jxp

特殊网格示例https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd#.xb74uu7ke