TouchEvent: dispatchTouchEvent(), onTouch() , onTouchEvent(), requestDisallowInterceptTouchEvent() 方法中的一些细节
Q: onTouchListener与onClickListener谁先执行?
A: onTouchListener中的内容先执行。若其中的onTouch方法返回true,代表该事件已被onTouch消费掉了,则onClick不会再执行。
Q: onTouch和onTouchEvent有什么区别?
A: 在某种情况下onTouch要先于onTouchEvent执行。onTouch是 onTouchListener 里的方法,若View已经设置了onTouchListener,且该View是 Enable 的,则会先尝试先调用onTouchListener中的onTouch方法,判断返回值。若onTouch方法返回false,则继续向下执行 onTouchEvent() 方法;若onTouch()方法返回true,则不再执行 onTouchEvent() 方法。
参考源码:
public boolean dispatchTouchEvent(MotionEvent event) {
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
Q: onClick()方法是在哪里调用的?是如何调用的?
A: onClick()方法是在onTouchEvent()方法中调用的。大概的调用流程为:当收到 MotionEvent.ACTION_UP 事件后,经过层层判断,会跳转到到 performClick() 方法中,在该方法中会判断onClickListener
是否为null, 若不为null,则会调用 onClickListener 的 onClick 方法。
参考源码: onTouchEvent

performClick()
public boolean performClick() {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
if (mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnClickListener.onClick(this);
return true;
}
return false;
}
Q: 有些时候在自定义View中的onTouchEvent()方法里添加GestureDetector时,无法响应GestureDetector里的触摸事件,这是为什么?
A: 可能是由于该View无法 clickable 导致的。观察源码的 onTouchEvent 方法就可以发现,如果View要响应 ACTION_UP , ACTION_MOVE ...等等诸如此类事件,先决条件就是该View必须是 CLICKABLE 或
LONG_CLICKABLE 的,二者满足其一即可。若二者皆不满足,则不会进入到接下来的 switch (event.getAction()) 代码块中。
参考源码:

Q: android里的Touch事件传递流程具体是怎么样的?
A: 当在屏幕上点击了一个控件,首先会去调用该控件所在的顶级布局中的 dispatchTouchEvent() 方法,然后在该方法中判断 if (disallowIntercept || !onInterceptTouchEvent(ev))
disallowIntercept 代表的是否禁用掉当前View的事件拦截功能,默认是 false ; onInterceptTouchEvent 代表的则是是否拦截其中的某一个事件,默认也是 false ,但是对onInterceptTouchEvent
进行了取反,也就意味着能够进入接下来的方法块当中,紧接着在该方法块中寻找符合点击位置的子控件,若找到了该子控件然后再去调用该子控件的dispatchTouchEvent()方法,最后调用该子控件的 onTouch 或
onTouchEvent() 方法对事件进行处理。
参考源码:

这几个方法的主要作用在于:
dispatchTouchEvent 负责事件的分发,
onInterceptTouchEvent 和 disallowIntercept 用于控制具体的触摸事件是否需要向对下层过滤
onTouch和onTouchEvent 负责具体的事件处理
正常的事件流向(以MyTextView为例):

Q: requestDisallowInterceptTouchEvent方法是干什么用的?
A: 这个方法的主要作用是用于修改上面的 disallowIntercept 这个变量的值,该方法传入一个bool变量,若为true,则代表禁用掉当前View的事件拦截功能。
参考链接:
1.Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
2.Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
TouchEvent: dispatchTouchEvent(), onTouch() , onTouchEvent(), requestDisallowInterceptTouchEvent() 方法中的一些细节的更多相关文章
- View中的onTouchEvent()与setOnTouchListener()中的ontouch()方法的事件处理先后顺序
Touch事件的两种情况 1.覆写View.class中定义的onTouchEvent-->基于事件回调监听方式 @Override public boolean onTouchEvent(Mo ...
- Android中onInterceptTouchEvent、dispatchTouchEvent及onTouchEvent的调用顺序及内部原理
在Android中需要经常对用户手势进行判断,在判断手势时需要精细的分清楚每个触摸事件以及每个View对事件的接收情况,在View,ViewGroup,Activity中都可以接收事件,在对事件进行处 ...
- ViewGroup dispatchTouchEvent方法中 mFirstTouchTarget标志是否为空的含义
在ViewGroup dispatchTouchEvent方法中首次出现mFirstTouchTarget的语句为: if (actionMasked == MotionEvent.ACTION_DO ...
- Android Touch事件之二:dispatchTouchEvent()和onTouchEvent()篇
2015-12-01 15:06:14 Android Touch事件第一篇:Touch事件在父ViewGroup和子View之间的传递简单分析了事件的传递流程,这次深入了解下dispatchTouc ...
- 关于dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的分发机制浅析
虽说这个问题不是很难...动动手就能看出答案...但是似乎不太容易理解...几次尝试把这个问题说明白....但是好像感觉说不明白....(顿时想起了那句话----说不明白就是自己还不明白! 我怎么可能 ...
- python方法中的self
前几天在写一个c作业时,突发奇想,在结构体中加入函数指针, 像这样: struct People { int _age; int (*age)(); }people; 这样调用时就可以 people. ...
- 解决webkit浏览器中js方法中使用window.event提示未定义的问题
这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...
- Don’t Use Accessor Methods in Initializer Methods and dealloc 【初始化和dealloc方法中不要调用属性的存取方法,而要直接调用 _实例变量】
1.问题: 在dealloc方法中使用[self.xxx release]和[xxx release]的区别? 用Xcode的Analyze分析我的Project,会列出一堆如下的提示:Inco ...
- jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法
jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法 在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...
随机推荐
- java 封装02
//Person.java public class Person{ private String name; private int age; private String sex; public ...
- php与redis使用经验分享 (转载)
一.安装 1.redis的下载及安装: 引用 mkdir /usr/local/redis cd /usr/local/redis wget http://redis.googlecode.com/f ...
- Ubuntu18.04下的 Android Studio 3.1.2
Android Studio安装 参考官网上的安装说明 # 安装依赖 :i386 lib32z1 libbz2-1.0:i386 安装openjdk (Update 2018-08-21: 这次重装U ...
- 转:Linux网卡驱动程序编写
Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大 ...
- 在QTableView中某列中添加Button的导致滚动条滚动的时候消失的问题
之前在项目上需要在表格中加入Button是按照以下两个文章的做法: http://www.cnblogs.com/li-peng/p/3961843.html http://www.cnblogs.c ...
- java非web应用修改 properties/xml配置文件后,无需重启应用即可生效---自动加载
实现时主要使用Commons-Configuration.jar包,还需要commons-lang,disgestor,beanutils,collections等, package propFile ...
- jsp+easyui+DataGrid 例子
转自:https://blog.csdn.net/l3922768721/article/details/51597977 导入js和css <%@ page language="ja ...
- ReactiveCocoa 中 RACSignal 是怎样发送信号
前言 ReactiveCocoa是一个(第一个?)将函数响应式编程范例带入Objective-C的开源库.ReactiveCocoa是由Josh Abernathy和Justin Spahr-Summ ...
- Spring事务异常回滚,捕获异常不抛出就不会回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
- js验证身份证类
var idCardNoUtil = { provinceAndCitys: {11:"北京",12:"天津",13:"河北",14:&qu ...