在安卓中,有許多關於如何使用RecyclerView實現“drag & drop”與swipe-to-dismiss”的教程,庫和例子。即使現在已經有了新的,更優的實現方式,大多數仍然是使用老舊的View.OnDragListener以及Roman
Nurik在SwipeToDismiss中所使用的方法。很少有人使用新的api,反而要麼經常依賴於GestureDetectors和onInterceptTouchEvent,要麼實現方式很複雜。實際上,在RecyclerView上添加拖動特性有一個非常簡單的方法。這個方法只需要一個類,並且它也是Android
兼容包的一部分,它就是:
ItemTouchHelper
ItemTouchHelper是一個強大的工具,它處理好了關於在RecyclerView上添加拖動排序與滑動刪除的所有事情。它是RecyclerView.ItemDecoration的子類,也就是說它可以輕易的添加到幾乎所有的LayoutManager和Adapter中。它還可以和現有的item動畫一起工作,提供受類型限制的拖放動畫等等。
使用 ItemTouchHelper 和 ItemTouchHelper.Callback
要使用ItemTouchHelper,你需要創建一個ItemTouchHelper.Callback。這個接口可以讓你監聽“move”與 “swipe”事件。這裏還是控制view被選中的狀態以及重寫默認動畫的地方。如果你只是想要一個基本的實現,有一個幫助類可以使用:SimpleCallback,但是爲了瞭解其工作機制,我們還是自己實現。
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {//重寫getMoivementFlags()方法來指
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; //定可以支持的拖動和滑動的方向。使用
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; //helperItemToooouchHelper.makeMovementFlages
return makeMovementFlags(dragFlags, swipeFlags); //(int,int)來構造返回的flag。上下爲drag,左右爲swipe
}
@Override
public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder,//拖動事件響應,重新排序
ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition)();
int targetPosition = target.getAdapterPosition();
Collections.swap(mItems,fromPosion,targetPosition);
notifyItemMove(fromPosition,targetPosition);
return true;
}
@Override
public void onSwiped(ViewHolder viewHolder, int direction) {//左右滑動事件響應,刪除item
int position = viewHOlder.getAdapterPosition();
mItems.remove(position);
notifyItemRemoved(position);
}
}
Callback準備好了之後,我們就可以創建我們的ItemTouchHelper並調用attachToRecyclerView(RecyclerView) 了
ItemTouchHelper.Callback callback =
new SimpleItemTouchHelperCallback(adapter);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerView);
運行之後,你可以看到如下的效果: