使用ItemTouchHelper实现RecyclerView的
2017-01-12 遇到的一点小问题
看自定义Behavior相关的文章时,还没看明白呢,看到ItemTouchHelper这个词,表示第一次见,搜了一下,好像很好用,不用自定义View就能让ItemTouchHelper实现拖拽排序和滑动删除之类的功能。而且简单多了,先试试这个。
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0630/3123.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0724/3219.html
这两个写得很详细,而且有demo,下载来看看就能大概明白基本的用法了。这边记录一下主要步骤,方便以后使用。
主要的就是写一个类extends继承android.support.v7.widget.helperItemTouchHelper.Callback
然后会提示重写几个方法
public class MyItemTouchHelperCallback 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()
这个方法是用来设置支持操作的方向,按源码写的,return makeMovementFlags(int dragFlags, int swipeFlags)
来区分拖拽或滑动往某个方向时可触发操作。比如,如果只能往右滑动才有反应就可以final int swipeFlags = ItemTouchHelper.END;
关闭这项功能则可以直接=0。
onMove()
是拖拽完成时,在这边通知适配器改变。
onSwiped()
是滑动完成时,在这边通知适配器改变。
为了让适配器及时收到通知,自定义一个接口,这样我们的Adapter就能implements ItemTouchHelperAdapter
来更新数据
public interface ItemTouchHelperAdapter {
boolean onItemMove(int fromPosition, int toPosition);
void onItemDismiss(int position);
}
再在自定义的MyItemTouchHelperCallback
写一个带ItemTouchHelperAdapter
的构造方法。
public MyItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
mAdapter = adapter;
}
在Activity里创建ItemTouchHelper
并绑定RecyclerView
,这样最基本的就没问题了。
ItemTouchHelper.Callback callback = new MyItemTouchHelperCallback(mAdapter);
ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(callback);
mItemTouchHelper.attachToRecyclerView(mRecycler);
默认长按item可时可进入拖拽准备状态,因为isLongPressDragEnabled()
这个方法默认return true
;item任意位置也能滑动,因为isItemViewSwipeEnabled()
默认return true
。
如果只是要在指定地方可操作,就按demo的来。先将刚才那两个方法改成return false
,然后将Adapter的某个View.setOnTouchListener
在
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN)
状态时,通知Activity里的ItemTouchHelper
执行.startDrag(viewHolder)
和.startSwipe(viewHolder)
方法。
holder.btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
mDragStartListener.onStartDrag(holder);
}
return false;
}
});
RecyclerView mRecycler = (RecyclerView) findViewById(R.id.recycler);
mRecycler.setLayoutManager(new LinearLayoutManager(context));
AdapteRecycler mAdapter = new AdapteRecycler(new OnStartDragListener() {
@Override
public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
mItemTouchHelper.startDrag(viewHolder);
mItemTouchHelper.startSwipe(viewHolder);
}
});
mRecycler.setAdapter(mAdapter);
mItemTouchHelper = new ItemTouchHelper(new MyItemTouchHelperCallback(mAdapter));
mItemTouchHelper.attachToRecyclerView(mRecycler);
demo里还有些细节,就是在自定义的ItemTouchHelper.Callback
里面重写一些相应的方法来改变item的样式。
onSelectedChanged
选中时;clearView
操作结束;或者重写onChildDraw
,根据坐标变换来及时绘制View。
以上都是看的 泡在网上的日子 那两篇博客和demo(https://github.com/iPaulPro/Android-ItemTouchHelper-Demo/releases)的记录,因为项目里还不用,所以不知道实际操作中会不会有问题。等有用到再更新。
list替换用的java.util.Collections
的public static void swap(List<?> list,int i,int j)
,好像都没用过,记一下,下次才知道。
接着看一下这个自定义Behavior相关(http://www.jianshu.com/p/f7989a2a3ec2 )。