为RecyclerView定制可滑动的Item
最近项目有需要弄一个可以像手机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的更多相关文章
- 修复垂直滑动RecyclerView嵌套水平滑动RecyclerView水平滑动不灵敏问题
在 Android 应用中,大部分情况下都会使用一个垂直滚动的 View 来显示内容(比如 ListView.RecyclerView 等).但是有时候你还希望垂直滚动的View 里面的内容可以水平滚 ...
- RecyclerView的使用之多种Item加载布局
精益求精,为了更加透彻熟练得掌握,本文再次给大家介石介绍下如何利用RecyclerView实现多Item布局的加载,多Item布局的加载的意思就是在开发过程中List的每一项可能根据需求的不同会加载不 ...
- Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果
本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877) 今天还是给大家带来自定义控件的编写,自定义一个Lis ...
- Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item
1. 这里就是实现一个很简单的功能,使用ListView实现左右滑动删除Item: (1)当我们在ListView的某个Item,向左滑动显示一个删除按钮,用户点击按钮,即可以删除该项item,并且有 ...
- 【转】Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
原文网址:http://blog.csdn.net/xiaanming/article/details/17539199 转帖请注明本文出自xiaanming的博客(http://blog.csdn. ...
- [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...
- Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...
- ListView 实现带有Filpper效果的左右滑动删除 Item
ListView 实现带有Filpper效果的左右滑动删除 Item 的实现最基本的方法还是 对 Listview 的继承重写 .然后是在删除过程中加入 TranslateAnimation 滑动事 ...
- ScrollView嵌套recyclerView出现的滑动问题
记得以前在解决scrollView与ListView嵌套问题时,那个时候是自定义了listView去测量listView高度,今天项目中刚 好碰到了要用recycerView,同样也是嵌套在scrol ...
随机推荐
- leetcode9 Palindrome Number(按进阶要求)
题目描述 Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same ...
- 各IDE代码自用开头模板
Pycharm #!/usr/bin/env python # -*- coding: utf-8 -*- # @version : 1.0 # @Time : ${DATE} ${TIME} # @ ...
- Jedis操作Redis--Hash类型
/** * Hash(哈希表) * HDEL,HEXISTS,HGET,HGETALL,HINCRBY,HINCRBYFLOAT,HKEYS,HLEN,HMGET,HMSET, HSET,HSETNX ...
- python控制窗口缩放
import win32gui import win32con import time # 使用之前先打开一个记事本 notepad = win32gui.FindWindow("Notep ...
- Photoshop软件破解补丁安装方法
参考: http://jingyan.baidu.com/article/454316ab4b3266f7a6c03a7d.html 1.安装好photoshop之后,解压32位64位破解补丁.zip ...
- Flask源码浅析
前言 学习一样东西,要先知其然,然后知其所以然. 这次,我们看看Flask Web框架的源码.我会以Flask 0.1的源码为例,把重点放在Flask如何处理请求上,看一看从一个请求到来到返回响应都经 ...
- vim命令的三种模式
对于vim这个命令来讲是有三种模式的,分别是:正常模式,编辑模式以及命令模式.接下来就写一个demo作为演示 前期准备,先在本地准备一个文档,我这里就写了一个大家耳熟能详的例子,如下: 然后用rz命令 ...
- 个推TechDay参会感悟
上周六去参加了个推和FCC联合在梦想小镇举办的TechDay,当然是作为台下听讲选手参与的,想上去讲可惜实力他不允许啊,吹牛逼我在行,讲技术可就有点虚了,老老实实的坐在台下听大佬们的分享,当然由于买了 ...
- mariadb 离线安装
[root@localhost local]# cd /var/local[root@localhost local]# lsmariadb[root@localhost local]# cd /ma ...
- Nginx 反向代理基本框架
全局配置指令:user nginx; 模块配置段 # 事件驱动模块,提供并发响应功能events{......}# http模块,提供web请求处理,可嵌套其他重要模块http{.......#ser ...