最近项目有需要弄一个可以像手机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. Leetcode Weekly Contest 152

    退役老人现在连leetcode都不会做了 = = 今天早上做了leetcode第三题题目看错了,加上比赛中间还在调投稿的实验,一心二用直接gg 总结下教训就是 本渣现在做题连题目都看不清就开始做.开始 ...

  2. Delphi - 使用Pos、Copy函数定位和截取字符串

    使用Pos函数来定位子字符串第一次出现的位置 函数定义: Function Pos(Substr: String, S: String): Integer; 表示取出Substr在S中第一次出现的位置 ...

  3. 一文读懂HashMap

    推荐 转载:https://www.jianshu.com/p/ee0de4c99f87

  4. hdu6219 Empty Convex Polygons (最大空凸包板子

    https://vjudge.net/contest/324256#problem/L 题意:给一堆点,求最大空凸包面积. 思路:枚举凸包左下角点O,dp找出以这个点为起始位置能构成的最大空凸包面积, ...

  5. Educational Codeforces Round 48 D Vasya And The Matrix

    EDU #48 D 题意:给定一个矩阵,已知每一行和每一列上数字的异或和,问矩阵上的数字是多少,不存在则输出NO. 思路:构造题,可以考虑只填最后一行,和最后一列,其中(n,m)要特判一下.其他格子给 ...

  6. codeforces 478 D. Red-Green Towers(背包)

    题目链接:http://codeforces.com/problemset/problem/478/D 题意:给出红色方块r个,绿色方块g个,问最高能叠几层等腰三角形,而且每一层的颜色必须相同. 题解 ...

  7. CF985C Liebig's Barrels 贪心 第二十

    Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  8. hud 1633 Orchard Trees 点是否在三角形内模板 *

    Orchard Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  9. Shiro实现用户对动态资源细粒度的权限校验

    前言 在实际系统应用中,普遍存在这样的一种业务场景,需要实现用户对要访问的资源进行动态权限校验. 譬如,在某平台的商家系统中,存在商家.品牌.商品等业务资源.它们之间的关系为:一个商家可以拥有多个品牌 ...

  10. Django+Nginx概念安装和使用–使用Django建立你的第一个网站

    一 前记 最近在使用Django倒腾属于自己的网站,由于以前没有接触过多少这类信息,所以,很多东西都是从零开始学习的.在参考网上的资料时候,发现很多对这方面记录的,很多人都写的不是很清楚,也许我这个新 ...