先简单看一下效果:
这种效果主要就是通过ItemTouchHelper类来实现的。
ItemTouchHelper在源码里的一段注释说明:
This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.
这是一个实用工具类,支持对RecyclerView的添加删除和拖放。
一般ItemTouchHelper和RecyclerView通过下面代码进行关联
ItemCallback callback = new ItemCallback(adapter);
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(recyclerview);
在ItemTouchHelper的构造方法里需要传入一个CallBack,它是ItemTouchHelper的内部类。我们要继承ItemTouchHelper的Callback类,重写它的三个方法。
public class ItemCallback1 extends ItemTouchHelper.Callback {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return 0;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
}
getMovementFlags()方法来指定可以支持的拖放和滑动的方向,它的返回值一般是通过makeMovementFlags(int dragFlags, int swipeFlags)方法来返回。
onMove方法,主要是拖动的时候,可以在这里监听进行数据更新的操作
onSwiped方法,主要是当item左右滑动造成数据变化时进行数据的更新。
所有数据的操作都是在Adapter里的,我们可以定义一个接口,让我们自定义的Adapter去实现这个接口,减少耦合的程度,
public interface ItemTouchHelperAdapterCallback {
boolean onItemMove(int fromPosition,int targetPosition);
void onItemSwiped(int position);
}
下面来看一下重写的三个方法的简单实现:
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags,swipeFlags);
}
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
我们定义上下都可以拖动,左右滑动都可以删除。
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if(callback!=null){
callback.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
}
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
if(callback!=null){
callback.onItemSwiped(viewHolder.getAdapterPosition());
}
}
callback就是刚才我们定义的接口,对数据的操作让Adapter去具体实现。
@Override
public boolean onItemMove(int fromPosition, int targetPosition) {
Collections.swap(datas,fromPosition,targetPosition);
notifyItemMoved(fromPosition,targetPosition);
return false;
}
@Override
public void onItemSwiped(int position) {
datas.remove(position);
notifyItemRemoved(position);
}
Adapter的实现也很简单,上下拖动的时候对数据源的两个位置的数据进行交换,同时用notifyItemMoved方法去更新两个position之间的布局刷新,不好用notifyDataSetChanged对所有item进行刷新。
左右滑动删除的时候就是将对应位置的数据源removed掉,然后调用notifyItemRemoved刷新布局。