实现RecyclerView拖动排序和滑动删除,我想到的是 ViewDragHelper ,或者是第三方库,当我看了 ToDoList 的时候,发现原来官方已经支持RecyclerView拖动排序与滑动删除,那就是ItemTouchHelper。
ItemTouchHelper简介
源码中的解释是这样的 :
This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.
大致说的是:这是一个RecyclerView的工具,提供了drag & swipe 的功能,也就是说 , 这个类可以帮助我们处理RecyclerView中Item的Drag和Swipe
It works with a RecyclerView and a Callback class, which configures what type of interactions are enabled and also receives events when user performs these actions.
大致说的是:他需要RecyclerView 还有ItemTouchHelper.CallBack配合使用,可以配置交互类型 , 并可以接收用户操作的事件 。也就是说 , 将ItemTouchHelper与RecyclerView关联之后 , CallBack可以接收到用户操作RecyclerView的事件 , 这样我们就可以做一些交互处理 。
ItemTouchHelper.CallBack分析
分析ItemTouchHelper之前,我们先看下CallBack的定义了那些方法
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
private DragSortItemLayout.OnItemSortListener mOnItemSortListener;
private boolean isLongPressDrag;
public ItemTouchHelperCallback(DragSortItemLayout.OnItemSortListener onItemSortListener) {
this.mOnItemSortListener = onItemSortListener;
}
/**
* 指定可以支持的拖放和滑动的方向,上下为拖动(drag),左右为滑动(swipe)
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 允许上下拖拽
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
// 禁止左右拖拽
int swipeFlags = 0;
return ItemTouchHelper.Callback.makeMovementFlags(dragFlags, swipeFlags);
}
/**
* 上下拖动时的回调
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
mOnItemSortListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
/**
* 左右滑动时的回调
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//这里可以处理删除操作
}
/**
* 操作Item的时候会不断调用绘制Item , 可自定义拖动与滑动交互
*/
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
/**
* Item选中状态的回调
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// We only want the active item to change
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Let the view holder know that this item is being moved or dragged
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
//选中Item状态回调
itemViewHolder.onItemSelected();
}
}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* Item选中后被释放的回调
* @param recyclerView
* @param viewHolder
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
//选中后释放Item的回调
itemViewHolder.onItemClear();
}
}
/**
* 是否允许长按触发拖拽
* @return
*/
@Override
public boolean isLongPressDragEnabled() {
return isLongPressDrag;
}
/**
* 是否允许item任意位置触发左右滑动
* @return
*/
@Override
public boolean isItemViewSwipeEnabled() {
return super.isItemViewSwipeEnabled();
}
public void setLongPressDragEnabled(boolean isLongPressDrag) {
this.isLongPressDrag = isLongPressDrag;
}
/**
* 返回值滑动消失的距离,滑动小于这个值不消失,大于消失
*/
@Override
public float getSwipeEscapeVelocity(float defaultValue) {
return super.getSwipeEscapeVelocity(defaultValue);
}
/**
* 返回值滑动消失的距离, 这里是相对于RecycleView的宽度,0.5f表示为RecycleView的宽度的一半,取值为0~1f之间
*/
@Override
public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
return super.getSwipeThreshold(viewHolder);
}
/**
* 返回值作为滑动的流程程度,越小越难滑动,越大越好滑动
*/
@Override
public float getSwipeVelocityThreshold(float defaultValue) {
return 1f;
}
/**
* 当用户拖动一个视图出界的ItemTouchHelper调用
*/
@Override
public int interpolateOutOfBoundsScroll(RecyclerView recyclerView, int viewSize, int viewSizeOutOfBounds, int totalSize, long msSinceStartScroll) {
return super.interpolateOutOfBoundsScroll(recyclerView, viewSize, viewSizeOutOfBounds, totalSize, msSinceStartScroll);
}
}
结合这些分析注释可大致了解CallBack里这些方法的意义,还有部分的方法还是没有理解到底是干嘛的所有就没有注释了。