为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 ...
随机推荐
- eslint语法规范
规则 缩进使用两个空格. eslint: indent function hello (name) { console.log('hi', name) } 1 2 3 字符串使用单引号,除 ...
- springBoot日志框架自动配置与原理
1.日志框架 小张:开发一个大型系统: 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? 2.框架来记录系统的一些运行时信息: ...
- C#开发BIMFACE系列1 BIMFACE 简介
系列目录 [已更新最新开发文章,点击查看详细] BIMFACE 是什么 BIMFACE = 国内领先的BIM轻量化引擎 BIMFACE 是广联达公司旗下的一款具有完全自主知识产权的BIM轻量化 ...
- 答辩过了,但我知道我写的是一坨shi
如果时间可以重来, 请好好珍惜大学里最重要的一份答卷. 以后的你会发现, 这种完全独立做出科研成果的机会, 可能不会再有. 1.保研了,才发现科研是多么难的一件事. 一直以来,读的喜欢的专业,考试成绩 ...
- A-Graph Games_2019牛客暑期多校训练营(第三场)
题意 给出一张无向图,定义S[x]表示与点x直接相连的点集,有两个操作 1 x y表示将第x到第y条边状态变化(若存在则删除,不存在则建立) 2 x y询问S[x]与S[y]是否相等 题解 有一个技巧 ...
- 牛客网暑期ACM多校训练营(第三场) A PACM Team 01背包 记录路径
链接:https://www.nowcoder.com/acm/contest/141/A来源:牛客网 Eddy was a contestant participating in ACM ICPC ...
- cf--703--A-- Mishka and Game
题目链接:http://codeforces.com/problemset/problem/703/A Mishka is a little polar bear. As known, little ...
- [在线+源码]vue全家桶+Typescript开发一款习惯养成APP
# vue-ts-daily 基于Vue.js的2.5.13版本和TypeScript编写的模仿原生应用的WebApp. [源码地址](https://github.com/xiaomuzhu/vue ...
- 每天学会一点点(JAVA基础)
1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? 虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件. Java被设计成允 ...
- webhook 自动部署代码
前话: 一般情况,自己在本地开发,代码改动后要push放到线上去看效果,但是我们还要到线上环境手动拉取代码库 git pull 下来, 一来一回太麻烦了. 现在用webhook就可以实现本地开发,pu ...