android 事件传递机制(1)
在项目中,经常遇到事件冲突,ScrollView,ViewPager滑动卡顿等情况,比如:onClick和onLongClick事件冲突,dispatchTouchEvent,onInterceptTouchEvent这些方法都有一个boolean返回值,不同返回值事件处理机制是不同的。
一:事件分发流程
1:现在有一个场景,用户长按button,我们希望只触发onLongClick,然而onClick事件也触发了.

这种情况比如简单,直接在onLongClick返回true就可以解决了,返回true表示onLongClick消费了这次事件。
2:view 和 viewGroup的介绍
View是所有UI组件的基类(如:TextView,Button,ImageView),而 ViewGroup是容纳这些组件的容器(如:LinearLayout,ReltiveLayout),ViewGroup是View派生出来的.
view有dispatchTouchEvent,onTouchEvent这两个方法,ViewGroup多了一个onInterceptTouchEvent方法,此方法决定触发事件是自己处理,还是分发给下一个组件处理.
2:事件涉及到的常用方法
用户点击屏幕时,将触发viewGroup的dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev);
3:方法返回值介绍
dispatchTouchEvent是处理触摸事件分发,事件(多数情况)是从Activity的dispatchTouchEvent开始的。执行super.dispatchTouchEvent(ev),事件向下分发。
onInterceptTouchEvent是ViewGroup提供的方法,默认返回false,返回true表示拦截,返回true后,由该类的onTouchEvent方法来执行。
onTouchEvent是View中提供的方法,ViewGroup也有这个方法,view中不提供onInterceptTouchEvent。view中默认返回true,表示消费了这个事件。
二:举一个栗子
1 老板将一个任务分配给经理,经理将任务分配给员工去完成,员工完成后,将结果反馈给经理,经理将任务结果反馈给老板,这是默认流程。

默认流程dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev),全部返回super.xxxxxxx

输出日志的结果
10-15 20:13:31.600 8716-8716/com.activity E/info: BossView dispatchTouchEvent() boss create task!
10-15 20:13:31.600 8716-8716/com.activity E/info: BossView onInterceptTouchEvent() boss将task 分配给manager
10-15 20:13:31.600 8716-8716/com.activity I/info: ManagerView 经理让onInterceptTouchEvent决定任务由谁完成
10-15 20:13:31.600 8716-8716/com.activity I/info: ManagerView onInterceptTouchEvent()经理接收到任务,将任务分配给员工
10-15 20:13:31.601 8716-8716/com.activity I/info: EmployeesView 员工开始工作.
10-15 20:13:31.601 8716-8716/com.activity I/info: EmployeesView 员工圆满完成任务.
10-15 20:13:31.602 8716-8716/com.activity I/info: ManagerView onTouchEvent() 经理验收任务结果,并向老板报告
10-15 20:13:31.602 8716-8716/com.activity E/info: BossView onTouchEvent() 工作已经完毕
2 老板将一个任务分配给经理,经理将任务分配给员工去完成,员工觉得难度大,无法完成(onTouchEvent返回true),由于老板没有接收到工作报告,会不停向经理分发任务(managerView的dispatchTouchEvent方法将不停被调用,员工的dispatchTouchEvent方法也会被继续调用)。

输出日志:

3 老板将一个任务分配给经理,因为上一次任务,经理并未收到员工的工作报告,所以这次经理决定,自己的来本次完成,将事件直接消费(onInterceptTouchEvent返回true),不分给员工去做,让员工一边凉快去 。

日志输出:
10-15 22:11:26.877 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_DOWN
10-15 22:11:26.878 22219-22219/com.activity E/info: BossView dispatchTouchEvent() boss create task!
10-15 22:11:26.879 22219-22219/com.activity E/info: BossView onInterceptTouchEvent() boss将task 分配给manager
10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView 经理让onInterceptTouchEvent决定任务由谁完成
10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView onInterceptTouchEvent()经理接收到任务安排,员工做得不好,自己来做任务
10-15 22:11:26.879 22219-22219/com.activity I/info: ManagerView onTouchEvent() 经理验收任务结果,并向老板报告
10-15 22:11:26.879 22219-22219/com.activity E/info: BossView onTouchEvent() 工作已经完毕
10-15 22:11:26.886 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.902 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.912 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.919 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_MOVE
10-15 22:11:26.921 22219-22219/com.activity I/info: MainActivity--dispatchTouchEvent()ACTION_UP
三:代码
由于代码差不多,这里只贴出ManagerView的代码,完整代码下载连接在文章下方
public class ManagerView extends LinearLayout {
private final String TAG="ManagerView ";
private int index=0;
public ManagerView(Context context) {
super(context);
}
public ManagerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(index==0){
Log.i("info",TAG+" onTouchEvent() 经理验收任务结果,并向老板报告");
}else{
Log.i("info",TAG+" onTouchEvent() 自己亲自来完成任务");
}
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
index = 0;
// if(index==0){
// Log.i("info",TAG+"onInterceptTouchEvent()经理接收到任务,将任务分配给员工");
// return super.onInterceptTouchEvent(ev);
// }else{
Log.i("info",TAG+"onInterceptTouchEvent()经理接收到任务安排,员工做得不好,自己来做任务");
return true;
// }
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("info",TAG+"经理让onInterceptTouchEvent决定任务由谁完成");
return super.dispatchTouchEvent(ev);
}
}
备注:上传代码时,我电脑github出了点小问题,如果代码有问题,请留言,代码下载地址:github
android 事件传递机制(1)的更多相关文章
- Android事件传递机制(转)
Android事件构成 在Android中,事件主要包括点按.长按.拖拽.滑动等,点按又包括单击和双击,另外还包括单指操作和多指操作.所有这些都构成了Android中的事件响应.总的来说,所有的事件都 ...
- Android事件传递机制详解及最新源码分析——ViewGroup篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...
- Android事件传递机制详解及最新源码分析——View篇
摘要: 版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于安卓事件传递机制相信绝大部分开发者都听说过或者了解过,也是面试中最常问的问题之一.但是真正能从源码角度理解具体事件传递流程的相信并不多, ...
- Android事件传递机制详解及最新源码分析——Activity篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在前两篇我们共同探讨了事件传递机制<View篇>与<ViewGroup篇>,我们知道View触摸事件是ViewGroup传递 ...
- Android事件传递机制总结
Android中控件的分类 Activity dispatchTouchEvent(MotionEvent e) onTouchEvent(MotionEvent e) ViewGroup(View) ...
- Android事件传递机制
http://blog.csdn.net/awangyunke/article/details/22047987 1)public boolean dispatchTouchEvent(MotionE ...
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()总结
老实说,这两个小东东实在是太麻烦了,很不好懂,我自己那api文档都头晕,在网上找到很多资料,才知道是怎么回事,这里总结一下,记住这个原则就会很清楚了: 1.onInterceptTouchEvent( ...
- android事件传递机制以及onInterceptTouchEvent()和onTouchEvent()详解二之小秘与领导的故事
总结的不是很好,自己也有点看不懂,正好现在用到了,研究了一个,再次总结,方便大家查看 总则: 1.onInterceptTouchEvent中有个Intercept,这是什么意思呢?她叫拦截,你大概知 ...
- android 事件传递机制
有三个方法: dispatchTouchEvent onInterceptTouchEvent onTouchEvent 首先:A的dispatchTouchEvent-A的onInterceptTo ...
随机推荐
- C#实现将输入的数自动转换为科学计数法
一朋友写了一个把输入的整型或浮点数转换为科学计数法表示的算法,写好后叫我去帮他看看有没有什么bug之类的没有考虑周全.我还没有细看就已经把我吓到了----整整写了将近三百行代码.我也没说他什么,只是回 ...
- 从java1到java9每个版本都有什么新特性?
每次出新版本,大家大概都会这么问,"Java X会有什么特性呢?" .在下面的内容里,我总结了至今为止的Java主要发行版中各自引入的新特性,这样做的目的是为了突出各个新特性是在哪 ...
- Javascript中prototype属性
prototype作为JS相对比较难理解的一个知识点,在这里发表下自己的理解. 本文将包含以下几部分内容: 1.js prototype的简单介绍, 2.js构造函数的介绍, 3.prototype的 ...
- Office2016 KMS激活
Office标准版激活 一新买本子需要安装Office,闲来无事就安装了一款Office Standard 2016,网上许多激活秘钥均已过期,无法激活,无奈下选择KMS激活. KMS下载链接如下: ...
- 谷歌浏览器 插件安装配置Momentum chrome
总之一句话就是这个Momentum插件可以把你的谷歌弄的漂亮一些,来搞一波 下载地址 http://www.cnplugins.com/down/predownnew.aspx?id=33842 下载 ...
- ASP.NET Core教程【三】实体字段属性、链接标签、并发数据异常、文件上传及读取
前文索引:ASP.NET Core教程[二]从保存数据看Razor Page的特有属性与服务端验证ASP.NET Core教程[一]关于Razor Page的知识 实体字段属性 再来看看我们的实体类 ...
- C#设计模式之十七观察者模式(Observer Pattern)【行为型】
一.引言 今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲& ...
- python语言 第一个程序
print("hello word!") # for i in range(1, 10):# for j in range(1, 10):# print(j, "x&qu ...
- 单节点下使用docker部署consul
部署consul 目前Consul使用的版本是: v1.0.1 本教程适用于刚刚开始学习consul并简单使用consul的同学,可以在短时间内了解conusl,配合官方文档https://www.c ...
- ctrl+z 以后怎么恢复挂起的进程
(1) CTRL+Z挂起进程并放入后台 (2) jobs 显示当前暂停的进程 (3) bg %N 使第N个任务在后台运行(%前有空格) (4) fg %N 使第N个任务在前台运行 默认bg,fg不带% ...