1,今天和大家一起实现RecyclerView可拖拽Item,主要是使用RecyclerView结合ItemTouchHelper来实现的,来看一下效果

2,看一下怎么实现的呢,很简单,只需要给recyclerView添加一个ItemTouchHelper对象就行

mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() );
mItemTouchHelper.attachToRecyclerView(mRecyclerView);

 构造方法中需要一个CallBack对象,适用于拖拽或者剔除时的回调方法,所以我们主要是要重写CallBack中的相应方法,处理响应的逻辑

首先来自定义一个CallBack类,继承与ItemTouchHepler.Callback()对象

            @Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { } @Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { } @Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { }

  首先说一下getMovementFlags(),这个方法是设置是否滑动时间,以及拖拽的方向,所以在这里需要判断一下是列表布局还是网格布局,如果是列表布局的话则拖拽方向为DOWN和UP,如果是网格布局的话则是DOWN和UP和LEFT和RIGHT,对应这个方法的代码如下:

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
} else {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
}
}

  而onMove()方法则是我们在拖动的时候不断回调的方法,在这里我们需要将正在拖拽的item和集合的item进行交换元素,然后在通知适配器更新数据,也很简单,代码如下:

            @Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//得到当拖拽的viewHolder的Position
int fromPosition = viewHolder.getAdapterPosition();
//拿到当前拖拽到的item的viewHolder
int toPosition = target.getAdapterPosition();
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(datas, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(datas, i, i - 1);
}
}
myAdapter.notifyItemMoved(fromPosition, toPosition);
return true;
}

  onSwiped()是替换后调用的方法,可以不用管。然后我们希望在拖拽的时候将被拖拽的Item高亮,这样用户体验要好很多,所以我们要重写CallBack对象中的onSelectedChanged()和clearView()方法,在选中的时候设置高亮背景色,在完成的时候移除高亮背景色,代码如下:

            /**
* 长按选中Item的时候开始调用
*
* @param viewHolder
* @param actionState
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
}
super.onSelectedChanged(viewHolder, actionState);
} /**
* 手指松开的时候还原
* @param recyclerView
* @param viewHolder
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setBackgroundColor(0);
}

  这样就实现了我们的基本要求,但是实际功能中有可能存在,排头前两个的不需改变它的顺序,即有些item允许拖拽,有些则不允许,所以我们需要重写isLongPressDragEnabled()设置不允许长按拖拽

             /**
* 重写拖拽不可用
* @return
*/
@Override
public boolean isLongPressDragEnabled() {
return false;
}

  然后在重写RecycleView的长按监听(这个要自己写个接口去实现),在返回的长按方法中判断是否为不可拖拽的item,若不是,则调用ItemTouchHelper的startDrag()方法,逻辑出入如下:

           @Override
public void onItemLongClick(RecyclerView.ViewHolder vh) {
//判断被拖拽的是否是前两个,如果不是则执行拖拽
if (vh.getLayoutPosition() != 0 && vh.getLayoutPosition() != 1) {
mItemTouchHelper.startDrag(vh); }
}

  为了功耗的用户体验 我们可以在长按的时候添加震动,添加权限

<uses-permission android:name="android.permission.VIBRATE" />

  调用方法:

 //获取系统震动服务
Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
//震动70毫秒
vib.vibrate(70);

  这样功能就差不多实现了,这是GitHub下载链接  See You Next Time !

Android -- 实现RecyclerView可拖拽Item的更多相关文章

  1. android ListView和GridView拖拽移位具体实现及拓展

    关于ListView拖拽移动位置,想必大家并不陌生,比较不错的软件都用到如此功能了.如:搜狐,网易,百度等,但是相比来说还是百度的用户体验较好,不偏心了,下面看几个示例:              首 ...

  2. android ListView和GridView拖拽移位实现代码

    关于ListView拖拽移动位置,想必大家并不陌生,比较不错的软件都用到如此功能了.如:搜狐,网易,百度等,但是相比来说还是百度的用户体验较好,不偏心了,下面看几个示例:             首先 ...

  3. Android 自动化测试—robotium(八) 拖拽

    本文来源于:http://xiaomaozi.blog.51cto.com/925779/933056 SeekBar控件 代码实现:http://luwenjie.blog.51cto.com/92 ...

  4. android开发游记:ItemTouchHelper 使用RecyclerView打造可拖拽的GridView

    以下是RecyclerView结合ItemTouchHelper实现的列表和网格布局的拖拽效果. 效果图例如以下:(gif图有点顿卡,事实上执行是非常流畅的) demo下载地址: DragRecycl ...

  5. Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)

    前言 上篇博客我们说到了今日头条频道管理的操作交互体验,我也介绍了2个GridView之间Item的相互移动.详情请參考:Android 仿今日头条频道管理(上)(GridView之间Item的移动和 ...

  6. RecyclerView拖拽排序和滑动删除实现

    效果图 如何实现 那么是如何实现的呢?主要就要使用到ItemTouchHelper ,ItemTouchHelper 一个帮助开发人员处理拖拽和滑动删除的实现类,它能够让你非常容易实现侧滑删除.拖拽的 ...

  7. Android中GridView拖拽的效果【android进化三十六】

      最 近看到联想,摩托罗拉等,手机launcher中有个效果,进入mainmenu后,里面的应用程序的图标可以拖来拖去,所以我也参照网上给的代码,写了 一个例子.还是很有趣的,实现的流畅度没有人家的 ...

  8. Android中GridView拖拽的效果

    最 近看到联想,摩托罗拉等,手机launcher中有个效果,进入mainmenu后,里面的应用程序的图标可以拖来拖去,所以我也参照网上给的代码,写了 一个例子.还是很有趣的,实现的流畅度没有人家的那么 ...

  9. 【WPF】拖拽ListBox中的Item

    整理了两个关于WPF拖拽ListBox中的Item的功能.项目地址 https://github.com/Guxin233/WPF-DragItemInListBox 需求一: 两个ListBox,拖 ...

随机推荐

  1. 随着应用对事务完整性和并发性要求的不断提高,MySQL才开始开发基于事务的存储引擎

    MYSQL 解锁与锁表 - 专注it - 博客园 https://www.cnblogs.com/wanghuaijun/p/5949934.html 2016-10-11 16:50 MYSQL 解 ...

  2. [daily] 主机间目录共享

    1. 安装 nfs工具 [root@D128 j]# yum install nfs-utils 2. 修改配置文件: 1.  查看一下语法. [root@D128 j]# man exports 2 ...

  3. Copycat - MemberShip

    https://github.com/atomix/copycat   http://atomix.io/copycat/docs/membership/   为了便于实现,Copycat把membe ...

  4. oracle优化:避免全表扫描

    http://blog.csdn.net/onetree2010/article/details/6098259

  5. jMeter_响应数据乱码

    jMeter测试时服务响应数据乱码 方式一:修改配置文件参数 1.修改jMeter安装目录 jmeter.properties 中 sampleresult.default.encoding=UTF- ...

  6. Java之旅_高级教_集合框架

    摘自:http://www.runoob.com/java/java-collections.html Java 集合框架 早在Java2之前,java 就提供了特设类.比如:Dictionary,V ...

  7. jquery图片懒加载效果

    1.要引入jquery 2.要引入underscore.js <!DOCTYPE html> <html lang="en"> <head> & ...

  8. scapy 中的ARP

    scapy 常用命令 ls() //查看支持的协议对象lsc() //查看函数show() //查看数据包结构send() //三层发包sr() //三层收发sr1() //三层收发只收一 timeo ...

  9. winform创建快捷方式

    /// <summary> /// 创建快捷方式 /// </summary> public class Lnk { /// <summary> /// 创建快捷方 ...

  10. JavaScript, DOM查找元素

    1.document.getElementById("id"); => IE8 及较低版本不区分ID的大小写 => IE7及较低版本中表单元素的name特性和ID都会被 ...