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 ...
随机推荐
- MyEclipse10激活方法
背景:因为以前一直使用的是myeclipse8.6版本,但因为版本太低有些功能不支持,于是想试用下myeclipse10.0版本,但是下载后发现需要激活,但在激活的过程中遇到了很多坑,于是便有了本文的 ...
- [转载] Java并发编程:Lock
转载自http://www.cnblogs.com/dolphin0520/p/3923167.html 以下是本文目录大纲: 一.synchronized的缺陷 二.java.util.concur ...
- [S]SQL SERVER数据库维护与重建索引
第一步:查看是否需要维护,查看扫描密度/Scan Density是否为100% declare @table_id int set @table_id=object_id('表名') dbcc sho ...
- [转]Oracle执行计划详解
Oracle执行计划详解 --- 作者:TTT BLOG 本文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html --- 简介: ...
- APP后台API文档管理对接(APP后台框架五)
这一章还是总结点API管理工具,也大都是组件来的,关于spring-rest-doc 以为很不错,其实还是有点局限性的: 1,每一个接口文档,都要自己手动设置文档的展示: 2,每一个接口就独立一个文档 ...
- 重温CSS3
基础不牢,地动山摇!没办法,只能重温"经典"! 1.CSS3边框:border-radius; box-shadow; border-image border-radius:r1, ...
- geotrellis使用(三十五)Cesium加载geotrellis TMS瓦片
前言 做任何事情都不是想象中的那么简单.好久没有更新技术博客了,跟最近瞎忙有很大关系,虽说是瞎忙也抽空研究了些技术. 主要是前端渲染,像原生的WebGL和Cesium.WebGL写了几篇博客,自我感觉 ...
- 《java.util.concurrent 包源码阅读》04 ConcurrentMap
Java集合框架中的Map类型的数据结构是非线程安全,在多线程环境中使用时需要手动进行线程同步.因此在java.util.concurrent包中提供了一个线程安全版本的Map类型数据结构:Concu ...
- python之列表(list)的使用方法介绍
python之列表(list)介绍 在python的使用过程中,我们经常会用到列表,然而经常会遇到疑惑,下面我将详细介绍下列表使用方法. 一.列表 列表经常用到的功能使增.删.改和查功能. 1. 增 ...
- JAVA基础5——与String相关的系列(2)
差异点比较 String使用+直接拼接 这种情况需要分两种情况来讨论: 1. 都是确定的字符串常量之间进行的+号拼接的时候,由于在编译器就可以确定其具体值了,所以编译器在编译期的时候就会把这些常量拼接 ...