一、效果图:

二、源码下载

下载地址:https://download.csdn.net/download/chaoyu168/10989276

三、原理

思路分析:

1、导包、在布局中使用RecyclerView

2、需要一个JavaBean用来存储展示信息

3、需要一个填充RecyclerView的布局文件

4、在代码中找到RecyclerView,并为其绑定Adapter和触摸事件

5、适配器的编写、触摸事件的处理

RecycleView实现拖拽交换位置的效果要简单很多,因为通过SDK中的ItemTouchHelper工具类可以轻松的实现这种效果,并且一套代码支持所有布局方式,只需要给recyclerView添加一个ItemTouchHelper对象就行。

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

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

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

//决定拖拽/滑动的方向
public abstract int getMovementFlags(RecyclerView recyclerView,ViewHolder viewHolder);//和位置交换有关,可用于实现drag功能
public abstract boolean onMove(RecyclerView recyclerView,ViewHolder viewHolder, ViewHolder target);//和滑动有关,可用于实现swipe功能
public abstract void onSwiped(ViewHolder viewHolder, int direction);//是否长按启用拖拽功能,默认是true
public boolean isLongPressDragEnabled() {return true;}//是否支持滑动,默认true
public boolean isItemViewSwipeEnabled() {return true;}//和目标View的状态改变有关,例如drag,swipe,ide
public void onSelectedChanged(ViewHolder viewHolder, int actionState) {}//和移除View的状态有关,通常用于清除在onSelectedChanged,onChildDraw中对View设置的动画
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {}

getMovementFlags() 
用于设置是否处理拖拽事件和滑动事件,以及拖拽和滑动操作的方向,有以下两种情况:

如果是列表类型的,拖拽只有ItemTouchHelper.UP、ItemTouchHelper.DOWN两个方向
如果是网格类型的,拖拽则有UP、DOWN、LEFT、RIGHT四个方向
另外,滑动方向列表类型的,有START和END两个方法,如果是网格类型的一般不设置支持滑动操作可以将swipeFlags = 0置为0,表示不支持滑动操作! 
最后,需要调用return makeMovementFlags(dragFlags, swipeFlags);将设置的标志位return回去!

对应这个方法的代码如下:

@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() 
如果我们设置了相关的dragFlags ,那么当我们长按item的时候就会进入拖拽并在拖拽过程中不断回调onMove()方法,我们就在这个方法里获取当前拖拽的item和已经被拖拽到所处位置的item的ViewHolder。

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {//得到当拖拽的viewHolder的Positionint fromPosition = viewHolder.getAdapterPosition();//拿到当前拖拽到的item的viewHolderint 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;
}

onSwipe() 
如果我们设置了相关的swipeFlags,那么当我们滑动item的时候就会调用onSwipe()方法,一般的话在使用LinearLayoutManager的时候,在这个方法里可以删除item,来实现滑动删除!

isLongPressDragEnabled()、isItemViewSwipeEnabled()

如果我们不重写这两个方法,那么拖拽和滑动都是默认开启的,如果需要我们自定义拖拽和滑动,可以设置为false,然后调用startDrag()startSwipe()方法来开启!

在拖拽的时候将被拖拽的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()方法,逻辑出入如下:

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

onSelectedChanged()

这个方法在选中Item的时候(拖拽或者滑动开始的时候)调用,通常这个方法里我们可以改变选中item的背景颜色等,高亮表示选中来提高用户体验。 
需要注意的是,这里的第二个参数int actionState,它有以下3个值,分别表示3种状态:

ACTION_STATE_IDLE:闲置状态
ACTION_STATE_SWIPE:滑动状态
ACTION_STATE_DRAG:拖拽状态
我们可以根据这个状态值,作不同的逻辑处理!

clearView()

这个方法在当手指松开的时候(拖拽或滑动完成的时候)调用,这时候我们可以将item恢复为原来的状态。

最后在代码中:

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new SimpleItemTouchCallback(data, adapter));
itemTouchHelper.attachToRecyclerView(recyclerView);

先得到ItemTouchHelper 实例,构造方法中传入我们自定义的Callback,然后调用attachToRecyclerView(recyclerView),传入需要绑定的RecyclerView即可!

Android--实现类似支付宝的功能拖拽、增删相关推荐

  1. 用RecyclerView实现类似支付宝应用图标拖拽排序以及增删管理的功能

    1. 效果图 2. 基本的功能 在非编辑状态下可以直接点击图标进行跳转 在编辑状态可以拖拽.添加.删除操作 已被添加过的不能再次添加 3. 实现的思路 用两个RecyclerView实现,同时维护两个 ...

  2. Android 贝塞尔曲线——类似QQ红点拖拽效果

    在Android绘制中,提供了更为丰富绘制api--Path类,包括直线,二阶贝塞尔曲线,三阶贝塞尔曲线,弧形,圆,椭圆,圆角矩形等等,path的绘制最终是调用了C中的绘制方法. 下面来看一下常用的几 ...

  3. 安卓开发仿微信图片拖拽_使用Android 模仿微信朋友圈图片拖拽返回

    1概述 目前的app的动画效果是越来越炫了,很多主流app的图片预览返回都有类似功能,比较常见的是ios自带相册,微信朋友圈等等.自己项目中也有类似功能,最近整理了一下这个功能的代码,做个笔记记录,有 ...

  4. Android 仿QQ未读消息拖拽删除粘性控件效果

    效果图: 分析  一 : 1.应用的地方:如未读数据的清除等 2.这个控件要实现哪些功能呢? 1)拖拽超出范围时,断开了,此时我们松手,图标消失 2)拖拽超出范围时,断开了,此时我们把图标移动回去,图 ...

  5. Android最简单的实现View拖拽跟随手指移动效果

    今天想实现这个功能,但是网上搜索代码,都是利用setPadding,setMargin 等方法去实现的,这在Android 4.0 以前是没问题的,但是,Android 4.0 后系统已经提供了更简单 ...

  6. android Viewpager HorizontalScrollView 实现分页栏拖拽

    源码:http://files.cnblogs.com/android100/ViewPaperDemo.rar 首先我们先看一个效果:  前两个是网易的,它做的title不能拖拽,.不过点击动画效果 ...

  7. Android开发学习之ImageView手势拖拽、缩放、旋转

    在Android应用中,图片随手势的拖拽.缩放.旋转在很多场景中都会用到,今天我们要做的就是在ImageView的基础上实现一个可以拖拽.缩放.转转的TouchView. 一.实现原理 OnTouch ...

  8. Android自定义View-模仿QQ的拖拽气泡

    第一步:明白气泡的几个状态 第二步:明白大概的思路 第三步:初始化组价的属性,并计算组件的大小 第四步:通过点击,拖动,取消,分别获取到两点之间的距离,然后得到组件的各个状态 第五步:绘制图像 1.如 ...

  9. Android自定义类似支付宝密码输入的控件

    前言:感觉自己记忆力不是很好,很多写过的东西容易忘记,所以还是写个博客记录一下,菜鸟一枚,望各位师傅指点. 嘿喂狗,来看我们要实现的效果(如果你说:"开发之前当然看不到效果,看个diao啊& ...

最新文章

  1. HTTP请求报文和HTTP响应报文(转)
  2. 闭包(Closures)
  3. opencv 计数后不动了 训练模型时_用OpenCV和深度学习进行年龄识别
  4. 程序员修炼之路:你该知道的 7 个必经阶段
  5. 2013年第四届蓝桥杯C/C++ A组国赛 —— 第五题:网络寻路
  6. 字典树(Trie)的java实现
  7. 【RK3399Pro学习笔记】五、ROS与USB摄像头
  8. 小程序分享到朋友圈_如何给小程序添加分享朋友圈
  9. QObject::startTimer: Timers cannot be started from another thread
  10. NDK开发才是有精华和特色的部分
  11. 双屏鼠标经常跑到副屏_双屏游戏本什么体验?上手ROG冰刃双屏:效率直接拉满...
  12. 机器学习中的正则化(Regularization)
  13. 机器人学导论—机器人相关术语
  14. 天堂2服务器自动停止,为什么我一进天堂2就与服务器连接中断??/
  15. OBS Studio下载速度慢,加速下载!11m/s
  16. Infragistsitcs NetAdvantage WebCombo 控件
  17. openssl心脏出血bug的补丁修复
  18. JAVA——反转的两种方法
  19. MAT之NSL:SOFM神经网络实现预测哪个样本与哪个样本处在同一层,从而科学规避我国煤矿突水灾难
  20. 计算机应用基础 题库,计算机应用基础题库

热门文章

  1. IE 兼容性问题记录
  2. 线性代数笔记-3Blue1Brown:(一)
  3. 《工业APP白皮书》发布,鼎捷软件ERP,MES等系统方案获专业推荐
  4. 02 java语言基础
  5. STM32学习笔记2:配置TCRT5000模块(红外传感模块)调用
  6. 【黑苹果】【高分屏】软件修改BIOS中DVMT等设置 Insyde BIOS 联想YOGA系列
  7. XTU OJ 1279 Dual Prime
  8. Unity Shader入门精要学习笔记 - 第7章 基础纹理
  9. 网络协议 终章 - GTP 协议:复杂的移动网络 1
  10. VISIONPRO中使用工业相机采集图像的两种方式分享