最近项目有需要弄一个可以像手机QQ会话页一样可以滑动的小菜单,每一个Item当用户在向左滑动的时候右侧会出现一个小菜单当时就想在也不是很难心想着找个开源的使用就好呢,但是我的项目是用的RecyclerView网上基本没有类似的没办法只能自己弄一个。

  先说一说我的实现原理我把每个Item看成一个LinearLayout它包含两个子控件一个是Item要显示的内容还有一个当然就是我们的右侧菜单了,这个顶部LinearLayout就是包含内容与菜单的容器,通过滚动这个容器的scrollX来显示我们的菜单,原理还是不难的,我把整个菜单的显示与隐藏把封闭在ItemSlideHelper里面这样想换一种方法实现也不用去别的代码很方便,当然ItemSlidHelper是要实现RecyclerView.OnItemTouchListener的因为我们的基本操作都是基于Touch事件的,有兴趣的可以看看,有BUG可以回复我。

  关于RecyclerView.OnItemTouchListener的几个方法我也学习了下也不是很难主要是拦截与操作这两个东西一定要配合好,还有就是RecyclerView的滚动状态,因为在RecyclerVIew滚动的时候我们的滑动菜单是不能操作的不然就会产生混乱,在项目开发的时候由于我的Item是有onClick事件的,那么在用户滑出菜单的时候也要把onClick事件给拦截但是又不能拦截菜单的Onclick事件我是通过容器的rect与scrollX的偏移来解决这个问题的可以看源码就知道呢。下面是拦截代码。

    @Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { if(!mCallback.isEnable())
return false; int action = MotionEventCompat.getActionMasked(e);
int x = (int) e.getX();
int y = (int) e.getY(); /*
* 当我们没有发生drag事件的时候cancel或up事件会发生interceptTouchEvent里面,如果TargetView等于空的时候直接
* 返回false,不拦截事件
* */
if(action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP)
if(mTargetView == null)
return false; boolean needIntercept = false;
switch (action) {
case MotionEvent.ACTION_DOWN: mActivePointerId = MotionEventCompat.getPointerId(e, 0);
mLastX = (int) e.getX();
mLastY = (int) e.getY(); //查找需要显示菜单的view;
mTargetView = mCallback.findTargetView(x, y); /*
* 如果正在动画则拦截事件
* */
if (mExpandAndCollapseAnim != null) {
//mExpandAndCollapseAnim.cancel();
mExpandAndCollapseAnim = null;
needIntercept = true;
}
break;
case MotionEvent.ACTION_MOVE: int deltaX = (x - mLastX);
int deltaY = (y - mLastY); if(Math.abs(deltaY) > Math.abs(deltaX))
return false; //如果移动距离达到要求,则拦截
needIntercept = mIsDragging = mTargetView != null && Math.abs(deltaX) >= mTouchSlop;
break; case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: /*
* 当一个up事件发生在正常的范围内且scrollX等于scrollRange则折叠view并拦截UP事件
* 防止view响应点击事件
* */
if(isExpanded()){ if (inView(x, y)) {
//拦截事件,防止targetView执行onClick事件
needIntercept = true;
}else{
//如果走这那行这个ACTION_UP的事件会发生在右侧的菜单中
} //折叠菜单
mTargetView.setScrollX(0);
}
dispatchCollapsedOrExpanded();
break;
} return needIntercept && mTargetView != null;
}

  对于滚动和动画的一些操作就比较简单了,没有DOWN事件是因为RecyclerView会在转发这个事件的事件故意不转发的可以看RecyclerViewr的dispatchOnItemTouch方法就知道了,在MOVE里面直接算一下移动的距离之类的就好了,通过deltaX来滚动容器的scrollX这样就可以实现在拖动时候显示或隐藏右侧的菜单。

  @Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) { //如果要响应fling事件设置将mIsDragging设为false
if (mGestureDetector.onTouchEvent(e)) {
mIsDragging = false;
return;
} int x = (int) e.getX();
int y = (int) e.getY();
int action = MotionEventCompat.getActionMasked(e);
switch (action) {
case MotionEvent.ACTION_DOWN:
//RecyclerView 不会转发这个Down事件 break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) (mLastX - e.getX());
horizontalDrag(deltaX);
mLastX = x;
break; case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: if(mIsDragging){
smoothHorizontalExpandOrCollapse(0);
} dispatchCollapsedOrExpanded();
mIsDragging = false; break;
} }

在使用的时候一定要调用下面代码将ItemslideHelper与RecyclerView关联起来.

        mRecyclerView.addOnItemTouchListener(new ItemSlideHelper(mRecyclerView.getContext(), this));

  

项目我已经传到Github上了

https://github.com/yjwfn/slideitem.git

为RecyclerView定制可滑动的Item的更多相关文章

  1. 修复垂直滑动RecyclerView嵌套水平滑动RecyclerView水平滑动不灵敏问题

    在 Android 应用中,大部分情况下都会使用一个垂直滚动的 View 来显示内容(比如 ListView.RecyclerView 等).但是有时候你还希望垂直滚动的View 里面的内容可以水平滚 ...

  2. RecyclerView的使用之多种Item加载布局

    精益求精,为了更加透彻熟练得掌握,本文再次给大家介石介绍下如何利用RecyclerView实现多Item布局的加载,多Item布局的加载的意思就是在开发过程中List的每一项可能根据需求的不同会加载不 ...

  3. Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877) 今天还是给大家带来自定义控件的编写,自定义一个Lis ...

  4. Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item

    1. 这里就是实现一个很简单的功能,使用ListView实现左右滑动删除Item: (1)当我们在ListView的某个Item,向左滑动显示一个删除按钮,用户点击按钮,即可以删除该项item,并且有 ...

  5. 【转】Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    原文网址:http://blog.csdn.net/xiaanming/article/details/17539199 转帖请注明本文出自xiaanming的博客(http://blog.csdn. ...

  6. [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...

  7. Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...

  8. ListView 实现带有Filpper效果的左右滑动删除 Item

    ListView 实现带有Filpper效果的左右滑动删除 Item  的实现最基本的方法还是 对 Listview 的继承重写 .然后是在删除过程中加入 TranslateAnimation 滑动事 ...

  9. ScrollView嵌套recyclerView出现的滑动问题

    记得以前在解决scrollView与ListView嵌套问题时,那个时候是自定义了listView去测量listView高度,今天项目中刚 好碰到了要用recycerView,同样也是嵌套在scrol ...

随机推荐

  1. CentOS 7下安装配置搭建jdk+tomcat+MariaDB环境

    1.JDK安装 注意:rpm与软件相关命令 相当于window下的软件助手 管理软件 步骤: 1)查看当前Linux系统是否已经安装java 输入 rpm -qa | grep java 2)卸载两个 ...

  2. MSIL实用指南-逻辑运算

    逻辑运算有三种:与.或.非.实现它们可以用位运算指令And.Or.Not等三个指令.它们的使用方法和位运算一致. 完整的程序如下: using System; using System.Reflect ...

  3. 前端开发-Web标准

    Web标准 1理解:结构 => html表现 => css行为 => js(dom + es) WEB标准(结构.表现.行为分离)有哪些优点呢? 易于维护:只需更改CSS文件,就可以 ...

  4. 第6章 事务管理 6.1 spring事务

    事务管理——原子性.一致性.隔离性.持久性 理解spring对事务管理的支持 Spring提供对编码式和声明式事务管理的支持.编码式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP,面 ...

  5. ABC133F - Colorful Tree

    ABC133FColorful Tree 题意 给定一颗边有颜色和权值的树,多次询问,每次询问,首先更改颜色为x的边的权值为y,然后输出u到v的距离. 数据都是1e5量级的. 思路 我自己一开始用树链 ...

  6. 使用Spring Boot和RxJava的构建响应式REST API

    我不打算解释什么是响应式编程,也不解释为什么要使用它.我希望你已经在其他地方了解过,如果没有,你可以使用Google去搜索它.在本文中,我将告诉您如何使用专门针对Spring Boot和RxJava的 ...

  7. 【Offer】[17] 【打印1到最大的n位数】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的3位数即999. 思路分析 要考虑到大数问题, ...

  8. IDEA中的各种快捷键

    1.get.set快捷键: Alt+Insert 2.idea补全返回值快捷键 比如写了一个new User(),需要补全前面的User user ctrl+alt+V 3.idea全局搜索: Ctr ...

  9. ubuntu下安装rtl8811cu/rtl8821cu网卡 Tplink WDN5200H网卡

    博客园第一篇博客,CSDN现在让人眼花缭乱了 @_@ 由于需要wifi调试,笔记本内置的网卡有点不太灵光,买了个TPLINK的WDN5200H AC网卡,给虚拟机用,折腾一下成功了github上有rt ...

  10. Nginx安装及详解

    Nginx简介: Nginx(发音engine x)专为性能优化而开发的开源软件,是HTTP.反向代理.邮件代理.TCP/UDP协议代理软件,由俄罗斯的作者Igor Sysoev开发,其最知名的优点是 ...