01.拖拽需要实现功能

  • 需要实现拖拽的功能如下所示

长按item后拖动,与其他item交换位置
按住item右面的图标后拖动,与其他item交换位置
左滑item变透明并缩小,超出屏幕后,其他item补上
右滑item变透明并缩小,超出屏幕后,其他item补上

02.几个重要的方法说明

  • 几个重要的方法说明

需要自定义类实现ItemTouchHelper.Callback类,并重写其中几个方法

isLongPressDragEnabled                  是否可以长按拖拽排序
isItemViewSwipeEnabled                  Item是否可以被滑动
getMovementFlags                        当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向
onMove                                  当Item被拖拽的时候被回调
onSwiped                                当View被滑动删除的时候
onSelectedChanged                       当item被拖拽或侧滑时触发

03.简单实现思路

  • 几个方法中代码思路

要想达到上面功能需求,在getMovementFlags方法中,当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向,那我们知道支持拖拽和滑动删除的无非就是LinearLayoutManager和GridLayoutManager了,所以可以根据布局管理器的不同做了响应的区分。

在onMove方法中处理拖拽的回调逻辑,那么什么时候被调用?当Item被拖拽排序移动到另一个Item的位置的时候被调用。在onSwiped方法[当Item被滑动删除到不见]中处理被删除后的逻辑。为了降低代码耦合度,可以通过接口listener回调的方式交给外部处理。

  • 上下拖动时与其他item进行位置交换

ItemTouchHelper.Callback本身不具备将两个item互换位置的功能,但RecyclerView可以,我们可以在item拖动的时候把当前item与另一个item的数据位置交换,再调用RecyclerView的notifyItemMoved()方法刷新布局,同时,因为RecyclerView自带item动画,就可以完成上面的交互效果。

  • 左右滑出屏幕时其他item补上

只要在item滑出屏幕时,将对应的数据删掉,再调用RecyclerView的notifyItemRemoved()方法刷新布局即可。

04.拖拽效果上优化

  • 拖拽效果优化

在item被拖拽或侧滑时修改背景色,当动作结束后将背景色恢复回来,而ItemTouchHelper.Callback中正好有对应这两个状态的方法,分别是:onSelectedChanged()、clearView()。那么优化处理其实可以放到这两个方法中处理。

左右滑动使item透明度变浅且缩小该如何实现呢?让item执行了两种属性动画而已,在ItemTouchHelper.Callback中有一个方法可以拿到item被拖拽或滑动时的位移变化,那就是onChildDraw()方法,在该方法中设置item渐变和缩放属性动画。

出现问题,按照上面做法会出现删除后有空白item留出来,那么为什么会出现这种情况呢?并不是多出了两条空白数据,它们是正常的数据,只是看不到了,这是因为RecyclerView条目(itemView)覆用导致的,前面在onChildDraw()方法中对itemView设置了透明和缩小,而一个列表中固定只有几个itemView而已,当那两个透明缩小的itemView被再次使用时,之前设置的透明度和高度比例已经是0,所以就出现了这种情况,解决方法也很简单,只要在item被移除后,将itemView的透明度和高度比例设置回来即可

05.完整代码展示

  • 代码的GitHub地址:github.com/yangchong21…
  • 完整代码如下所示
/*** <pre>*     @author 杨充*     blog  : https://github.com/yangchong211*     time  : 2017/5/2*     desc  : 自定义ItemTouchHelper*     revise: 参考严正杰大神博客:https://blog.csdn.net/yanzhenjie1003/article/details/51935982* </pre>*/
public class ItemTouchHelpCallback extends ItemTouchHelper.Callback {/*** Item操作的回调,去更新UI和数据源*/private OnItemTouchCallbackListener onItemTouchCallbackListener;/*** 是否可以拖拽*/private boolean isCanDrag = false;/*** 是否可以被滑动*/private boolean isCanSwipe = false;/*** 按住拖动item的颜色*/private int color = 0;public ItemTouchHelpCallback(OnItemTouchCallbackListener onItemTouchCallbackListener) {this.onItemTouchCallbackListener = onItemTouchCallbackListener;}/*** 设置是否可以被拖拽** @param canDrag 是true,否false*/public void setDragEnable(boolean canDrag) {isCanDrag = canDrag;}/*** 设置是否可以被滑动** @param canSwipe 是true,否false*/public void setSwipeEnable(boolean canSwipe) {isCanSwipe = canSwipe;}/*** 设置按住拖动item的颜色* @param color     颜色*/public void setColor(@ColorInt int color){this.color = color;}/*** 当Item被长按的时候是否可以被拖拽** @return                      true*/@Overridepublic boolean isLongPressDragEnabled() {return isCanDrag;}/*** Item是否可以被滑动(H:左右滑动,V:上下滑动)* isItemViewSwipeEnabled()返回值是否可以拖拽排序,true可以,false不可以* @return                      true*/@Overridepublic boolean isItemViewSwipeEnabled() {return isCanSwipe;}/*** 当用户拖拽或者滑动Item的时候需要我们告诉系统滑动或者拖拽的方向* 动作标识分:dragFlags和swipeFlags* dragFlags:列表滚动方向的动作标识(如竖直列表就是上和下,水平列表就是左和右)* wipeFlags:与列表滚动方向垂直的动作标识(如竖直列表就是左和右,水平列表就是上和下)** 思路:如果你不想上下拖动,可以将 dragFlags = 0*      如果你不想左右滑动,可以将 swipeFlags = 0*      最终的动作标识(flags)必须要用makeMovementFlags()方法生成*/@Overridepublic int getMovementFlags(@NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder viewHolder) {RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();if (layoutManager instanceof GridLayoutManager) {// flag如果值是0,相当于这个功能被关闭int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT| ItemTouchHelper.UP | ItemTouchHelper.DOWN;int swipeFlag = 0;// create makereturn makeMovementFlags(dragFlag, swipeFlag);} else if (layoutManager instanceof LinearLayoutManager) {LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;int orientation = linearLayoutManager.getOrientation();int dragFlag = 0;int swipeFlag = 0;// 为了方便理解,相当于分为横着的ListView和竖着的ListView// 如果是横向的布局if (orientation == LinearLayoutManager.HORIZONTAL) {swipeFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;} else if (orientation == LinearLayoutManager.VERTICAL) {// 如果是竖向的布局,相当于ListViewdragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;}//第一个参数是拖拽flag,第二个是滑动的flagreturn makeMovementFlags(dragFlag, swipeFlag);}return 0;}/*** 当Item被拖拽的时候被回调** @param recyclerView          recyclerView* @param srcViewHolder         当前被拖拽的item的viewHolder* @param targetViewHolder      当前被拖拽的item下方的另一个item的viewHolder* @return                      是否被移动*/@Overridepublic boolean onMove(@NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder srcViewHolder,@NonNull RecyclerView.ViewHolder targetViewHolder) {if (onItemTouchCallbackListener != null) {int srcPosition = srcViewHolder.getAdapterPosition();int targetPosition = targetViewHolder.getAdapterPosition();return onItemTouchCallbackListener.onMove(srcPosition, targetPosition);}return false;}/*** 当item侧滑出去时触发(竖直列表是侧滑,水平列表是竖滑)** @param viewHolder            viewHolder* @param direction             滑动的方向*/@Overridepublic void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {if (onItemTouchCallbackListener != null) {onItemTouchCallbackListener.onSwiped(viewHolder.getAdapterPosition());}}/*** 当item被拖拽或侧滑时触发** @param viewHolder            viewHolder* @param actionState           当前item的状态*/@Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {super.onSelectedChanged(viewHolder, actionState);//不管是拖拽或是侧滑,背景色都要变化if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {if (color==0){viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(android.R.color.darker_gray));}else {viewHolder.itemView.setBackgroundColor(color);}}}/*** 当item的交互动画结束时触发** @param recyclerView          recyclerView* @param viewHolder            viewHolder*/@Overridepublic void clearView(@NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder viewHolder) {super.clearView(recyclerView, viewHolder);viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(android.R.color.white));viewHolder.itemView.setAlpha(1);viewHolder.itemView.setScaleY(1);}@Overridepublic void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder viewHolder,float dX, float dY, int actionState, boolean isCurrentlyActive) {super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {float value = 1 - Math.abs(dX) / viewHolder.itemView.getWidth();viewHolder.itemView.setAlpha(value);viewHolder.itemView.setScaleY(value);}}public interface OnItemTouchCallbackListener {/*** 当某个Item被滑动删除的时候** @param adapterPosition   item的position*/void onSwiped(int adapterPosition);/*** 当两个Item位置互换的时候被回调** @param srcPosition       拖拽的item的position* @param targetPosition    目的地的Item的position* @return                  开发者处理了操作应该返回true,开发者没有处理就返回false*/boolean onMove(int srcPosition, int targetPosition);}
}
  • 如何使用,代码如下所示
ItemTouchHelpCallback callback = new ItemTouchHelpCallback((srcPosition, targetPosition) -> {if (imageBeans != null) {try {// 更换数据源中的数据Item的位置。更改list中开始和结尾position的位置Collections.swap(imageBeans, srcPosition, targetPosition);// 更新UI中的Item的位置,主要是给用户看到交互效果mAdapter.notifyItemMoved(srcPosition, targetPosition);} catch (Exception e){e.printStackTrace();}return true;}return true;});
callback.setDragEnable(true);
callback.setSwipeEnable(true);
callback.setColor(this.getResources().getColor(R.color.base_background_block));
//创建helper对象,callback监听recyclerView item 的各种状态
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
try{//关联recyclerView,一个helper对象只能对应一个recyclerViewitemTouchHelper.attachToRecyclerView(recyclerView);
}catch (Exception e){e.printStackTrace();
}

在这分享一份整理了2个月的Android进阶面试解析笔记文档,包括了知识点笔记和高频面试问题解析及部分知识点视频讲解给大家!为了不影响阅读,在这以图片展示部分内容于目录截图,有需要的朋友麻烦点赞后点击下面在线链接获取免费领取方式吧!
阿里P6P7【安卓】进阶资料分享+加薪跳槽必备面试题

ItemTouchHelper 实现交互动画相关推荐

  1. RecyclerView之使用ItemTouchHelper实现交互动画

    一.简述 RecyclerView默认就有item动画,例如在增加或删除item时,都会有一个条目间位移的动画,但本文要说的不是这个!!!本文的主角是v7包中的ItemTouchHelper,它跟Re ...

  2. Android ItemTouchHelper实现RecyclerView交互动画

    在上一次博客 Android RecyclerView使用详解,主要介绍了RecyclerView的基础使用,本篇文章将主要介绍通过ItemToucheHelper辅助类完成RecyclerView的 ...

  3. android:RecyclerView交互动画(上下拖动,左右滑动删除)

    效果 RecyclerView交互动画主要使用的是ItemTouchHelper这个类 创建MyItemTouchHelperCallback继承系统ItemTouchHelper.Callback ...

  4. Android开发之RecyclerView的交互动画(实现拖拽和删除)

    做RecyclerView做相关的动画效果的时候,用的最多的是v7包下的ItemTouchHelper类,这个类很强大,如有兴趣的童鞋可以自行翻看源码,接下来我带领大家实现RecyclerView相关 ...

  5. js svg语音波动动画_让动效更酷炫!4 个常见且常用的 SVG 交互动画方法

    本文介绍了 4 种常见的 SVG 交互动画方法,帮你了解 SVG 交互动画的原理和简单方法. 优秀的人机交互和舒适合理的动画,一直是 UX 设计师孜孜不倦追求的目标.但 UX 设计师每天都遇到能做出效 ...

  6. 交互 点击变色_这个95%的人都没用过的PPT功能,几分钟帮你做出发布会级的交互动画...

    我赌五毛,你一定没用过这个位于PPT插入选项卡的动作功能: 三顿就是用这个不起眼的小功能,制作了超多酷炫的交互动画.比如在做APP产品介绍时,点击左侧的按钮就能一键更换背景和产品图片: 甚至不用点击! ...

  7. [转]收集android上开源的酷炫的交互动画和视觉效果:Interactive-animation

    原文链接:http://www.open-open.com/lib/view/open1411443332703.html 描述:收集android上开源的酷炫的交互动画和视觉效果. 1.交互篇 2. ...

  8. Principle for Mac:让你五分钟即可制作出一个具有完整交互动画的原型

    Principle for Mac这款交互设计工具让你五分钟即可制作出一个具有完整交互动画的原型,并且可将交互动画生成视频或者 Gif 分享到 Dribbble.twitter 等社交平台. 无论您设 ...

  9. iOS添加自定义转场动画和交互动画(一)

    准备写两篇,第一篇介绍下转场动画,第二篇介绍下我封装的一个转场动画的库,可以很简便的给VC之间的转变加上自定义动画. iOS场景对应的类是ViewController,基本上一个场景对应一个VC,从一 ...

最新文章

  1. Jenkins 快速上手指南
  2. 前端每日实战:143# 视频演示如何用 CSS 的 Grid 布局创作一枚小松鼠邮票
  3. 7 php程序的调试方法_PHP程序错误调试方法 让php显示错误提示
  4. 仅需少量视频观看记录,就可以精准推断你的习惯
  5. 太辛苦的钱,我建议不要挣
  6. 南孚电池:如何从0-1建立经营分析报表平台,助力集团转型?
  7. 边缘计算的前景和挑战
  8. linux虚拟机上挂载U盘
  9. oracle把字段选为候选键,Oracle数据库试题及答案
  10. Electron 键盘快捷键
  11. grep的常用和次常用选项
  12. memcmp函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用、自己实现函数 )
  13. 适合苹果4s的微信版本_苹果:这些旧 iPhone 有重大缺陷,怕不怕?
  14. linux服务器端口使用drcom拨号联网
  15. android 遥控器方向,android万能遥控器之一--前言及发射部分的简单实现
  16. 华为芯片设计面试题_华为公司面试硬件工程师笔试题
  17. java系统_Java 系统
  18. 替代触发器和系统触发器
  19. 如何做好描述统计分析?
  20. seo外链建设(如何正确做好seo网站外链建设)

热门文章

  1. 单相半波可控整流电路实验报告matlab,单相半波可控整流电路实验报告
  2. echarts数据可视化(仪表盘)
  3. 不想写日报、周报?这款报表自动化工具一定要收好,打工人必备
  4. matlab选哪几个产品,MATLAB产品大全
  5. Flink之Souce
  6. Source Insight常用配置
  7. java毕业设计基于VUE的个人记账管理系统mybatis+源码+调试部署+系统+数据库+lw
  8. NFC读写MifareClassic协议的NFC卡
  9. 系统资源不足,无法完成请求的任务 解决方案
  10. k型热电偶材料_K型热电偶规格参数及使用性质.doc