RecyclerView使用指南

ItemTouchHelper使用

ItemTouchHelper是用来做一些RecyclerView Item拖动(drag)和移除(swipe)的。
1.gif
拖动和移除是两种不同的触发方式。拖动的话需要长按item,才会进入拖动的状态,而滑动不需要任何其他操作来进入滑动状态。因为拖动的这个神奇的触发方式,让我误认为拖动并没有效果,浪费了很多时间。

ItemTouchHelper主要在于重写Callback,Callback主要有三个方法需要重写,getMoveMentFlags,onMove,onSwiped。

getMoveMentFlags用来确定拖动和滑动的行为。这里,动作被分为三种状态:idle,drag,swipe。这里直接通过例子来说明:

1
makeFlag(ACTION_STATE_IDLE, RIGHT) | makeFlag(ACTION_STATE_SWIPE, LEFT | RIGHT);

这说明当idle的状态下可以向右滑动来让item进入滑动的状态,并且可以左右滑动来让item滑动移除出屏幕。

onMove是在drag状态下会被调用,有两个viewHolder,第一个是被拖动的Item,第二个是被拖动Item当前位置的Item。

如果这个方法返回为true,那么ItemTouchHelper假设被拖动的Item已经被拖动到了新的位置。If this method returns true, ItemTouchHelper assumesviewHolderhas been moved to the adapter position oftargetViewHolder (ViewHolder#getAdapterPositionInRecyclerView()).,这是google的文档,而对于文档的翻译我还是不知道返回true和false的区别是什么,而且在试验之后也没有发现什么不同,唯一能知道的是,在onMove返回true之后会调用下面这个方法。

1
2
3
4
5
6
7
public void onMoved (RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
int fromPos,
RecyclerView.ViewHolder target,
int toPos,
int x,
int y)

根据文档的描述,拖动的原理并不是重新创建了一个View,而是直接在原有的item上面进行操作,所以我们不能将item拖动到RecyclerView之外。

onSwiped这个方法会在item平移出RecyclerView的时候调用,类似之前使用过的滑动删除效果,这次需求的交互要求没有这个,所以暂时不考虑。

如果对自定义Callback感觉到没有那么定制化的必要的话,那么可以SimpleCallback,一个Callback的包装类。

Item