RecyclerView 滑动删除与拖动的实现
2016-06-15 15:54
459 查看
RecyclerView 滑动删除与拖动的实现
前言
记得很久以前做APP应用的时候,项目组老大说网易的栏目管理那块,可拖动排序蛮好看的,我们的应用也要那么做,后来我就在网上百度一番,找到用GridView的实现,最近游览网页,在网上看见有用RecyclerView实现的,自己也按照文章上的写了,看了一下,觉得写的蛮好的,不过有些地方的注释写的不全,所以我也写了一篇记录下来,参考文地址在这里,感谢这位作者,使我又学会了很多。实现原理
主要是借助 ItemTouchHelper.Callback 类来实现,我们要关注的方法为* getMovementFlags( )
* onMove()
* onSwiped()
* onSelectedChanged()
* clearView()
* isLongPressDragEnabled()
只需要重写这些方法,就能得到我们想要的结果。
拖动实现
首先自定义一个MyCallback类继承 ItemTouchHelper.Callback ,定义两个int变量dragFlags 与 swipeFlags 并实现下方法。getMovementFlags()
这个方法主要是为了获取我们当前的事件是拖动还是滑动dragFlags = 0; swipeFlags = 0; if (recyclerView.getLayoutManager() instanceof GridLayoutManager || recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager) { dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; } else { dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; } return makeMovementFlags(dragFlags, swipeFlags);
首先在这里为我们的标志符赋值为0,然后通过 ItemTouchHelper 来为标识符赋值。
onMove()
在该方法的注释中有这一段说明viewHolder The ViewHolder which is being dragged by the user.
target The ViewHolder over which the currently active item is being dragged.
这两个都是onMove提供的参数,从注释中可以看出viewHolder是起始位置,而target是目标位置,那么我们就好办了
int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); //这里的toPosition和fromPosition结合可以设置那一项不能改变 if (toPosition >= 2 && fromPosition != 0 && fromPosition !=1){ if (fromPosition < toPosition) { //向下拖动 for (int i = fromPosition; i < toPosition; i++) { Collections.swap(mListData, i, i + 1); } }else { //向上拖动 for (int i = fromPosition; i > toPosition; i--) { Collections.swap(mListData, i, i - 1); } } recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition); } return true;
这里我设置了前两项不可交换位置,往往我们都会有这样的需求。通过Collections 来交换数据,最后通过ecyclerView.getAdapter().notifyItemMoved 来刷新页面。
与RecyclerView绑定
通过ItemTouchHelper的attachToRecyclerView方法与RecyclerView绑定在一起ItemTouchHelper helper = new ItemTouchHelper(new MyItemTouchHelperCallback()); helper.attachToRecyclerView(mRecyclerView);
其中的MyItemTouchHelperCallback就是我们的自定义继承了 ItemTouchHelper.Callback 类的实现。这样并没有长按出现的效果,用户体验不好,可在下面的方法中实现。
onSelectedChanged
我们可以在这个方法中自定义用户长按后出现的效果,我这里就只设置了放大。if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { viewHolder.itemView.setScaleX(1.05f); viewHolder.itemView.setScaleY(1.05f); }
如果只设置了方法,而不设置缩小。那么肯定是不行的,我们在下面的方法中去还原View。
clearView
当事件结束后,我们可以在这里做一些处理,比如上面的还原View。viewHolder.itemView.setScaleX(1.0f); viewHolder.itemView.setScaleY(1.0f);
到这里我们的拖动就结束了,下面我们再来实现滑动删除。
滑动删除
滑动删除和拖动也是一样的实现思路,也是通过getMovementFlags获取事件,我们在前面的代码中添加如下代码swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
这样就可以了,如果你只想GridLayoutManager或LinearLayoutManager有滑动删除,那么可以把代码添加到上面的if判断里面去。
onSwiped
删除的实现,这是一个抽象方法,我们必须实现的。int position = viewHolder.getAdapterPosition(); mRecyclerView.getAdapter().notifyItemRemoved(position); mListData.remove(position);
这个方法比较简单,就是删除数据,更新页面。
如果你不想你的某一些项不可以滑动删除,那么就可以在前面的getMovementFlags去做判断,只要不为swipeFlags赋值就可以了。
isLongPressDragEnabled
该方法默认所有的项都可以拖动,在这里直接返回false,然后在为RecyclerView添加的事件监听中为长按事件添加如下代码就可以了
helper.startDrag(vh);
这样该Item项就可以拖动了,其中的helper为上面的ItemTouchHelper,vh就不用解释了吧。
如果对于RecyclerView的Item点击事件还不了解的可以阅读RecyclerView item点击你真的会么
总结
RecyclerView是如此的强大,对于滑动与拖动,只需要弄明白上面的6个方法的调用顺序,各个方法的任务。其中最重要的就是 getMovementFlags 了,如果这里弄错了,那么后面的都没用。相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories