列表的上下移动和滑动删除是不是经常看到,如何实现呢?其实使用ItemTouchHelper可以轻松实现。闲话不多说,先看效果。
先看一下官方的介绍
This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.
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添加条目滑动和拖拽的扩展工具类,它需要和一个回调类配合工作,通过配置交互方式的启用以及当我们执行操作时接受这些事件。
官方的构造方法是这样说的
/**
* Creates an ItemTouchHelper that will work with the given Callback.
*
* You can attach ItemTouchHelper to a RecyclerView via
* {@link #attachToRecyclerView(RecyclerView)}. Upon attaching, it will add an item decoration,
* an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
*
* @param callback The Callback which controls the behavior of this touch helper.
*/
public ItemTouchHelper(Callback callback) {
mCallback = callback;
}
看到这里的介绍你是不是一目了然了,还等什么,行动起来。
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new Callback());
itemTouchHelper.attachToRecyclerView(recyclerView);
接下来我们要自定义一个Callback来开启一个交互方式权限并执行一些用户操作。
API介绍:
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = 0;
int result = makeMovementFlags(dragFlags, swipeFlags);
其次是处理上下移动的事件,onMove给我们提供很方便的回调。
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcViewHolder,
RecyclerView.ViewHolder targetViewHolder){
boolean result = itemTouchMoveListener.onItemMove(srcViewHolder.getAdapterPosition(),
targetViewHolder.getAdapterPosition());
return result;
}
srcViewHolder : 是按住的那个条目
targetViewHolder: 移动到的那个条目
得到这两个条目的位置,通过回调告诉adapter进行移动操作。
如何支持左右滑动呢?同样是支持对应的权限
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
处理滑动删除事件
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcViewHolder,
RecyclerView.ViewHolder targetViewHolder) {
boolean result = itemTouchMoveListener.onItemMove(srcViewHolder.getAdapterPosition(),
targetViewHolder.getAdapterPosition());
return result;
}
接下来通过回调告诉了adapter需要操作的条目,就可以进行移动和删除对应的操作。
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(contents,fromPosition,toPosition);
notifyItemMoved(fromPosition,toPosition);
return false;
}
@Override
public boolean onItemRemove(int position) {
contents.remove(position);
notifyItemRemoved(position);
return true;
}
下面是完整的代码
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new CommonItemMoveCallback(itemMoveAdapter));
itemTouchHelper.attachToRecyclerView(recyclerView);
public class CommonItemMoveCallback extends ItemTouchHelper.Callback {
private ItemTouchMoveListener itemTouchMoveListener;
public CommonItemMoveCallback(ItemTouchMoveListener itemTouchMoveListener) {
this.itemTouchMoveListener = itemTouchMoveListener;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
int result = makeMovementFlags(dragFlags, swipeFlags);
return result;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcViewHolder,
RecyclerView.ViewHolder targetViewHolder) {
boolean result = itemTouchMoveListener.onItemMove(srcViewHolder.getAdapterPosition(),
targetViewHolder.getAdapterPosition());
return result;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
itemTouchMoveListener.onItemRemove(viewHolder.getAdapterPosition());
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
/**
*
* @param viewHolder
* @param actionState
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
}
@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);
}
}
后面有三个方法,可以实现点击拖拽滑动时更改背景颜色,以及滑动到固定位置,实现类似QQ侧滑删除效果。 后续更新出来