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事件分发机制完全解析,带你从源码的角度彻底理解(下)

3.Android的Touch事件分发机制简单探析

TouchEvent: dispatchTouchEvent(), onTouch() , onTouchEvent(), requestDisallowInterceptTouchEvent() 方法中的一些细节的更多相关文章

  1. View中的onTouchEvent()与setOnTouchListener()中的ontouch()方法的事件处理先后顺序

    Touch事件的两种情况 1.覆写View.class中定义的onTouchEvent-->基于事件回调监听方式 @Override public boolean onTouchEvent(Mo ...

  2. Android中onInterceptTouchEvent、dispatchTouchEvent及onTouchEvent的调用顺序及内部原理

    在Android中需要经常对用户手势进行判断,在判断手势时需要精细的分清楚每个触摸事件以及每个View对事件的接收情况,在View,ViewGroup,Activity中都可以接收事件,在对事件进行处 ...

  3. ViewGroup dispatchTouchEvent方法中 mFirstTouchTarget标志是否为空的含义

    在ViewGroup dispatchTouchEvent方法中首次出现mFirstTouchTarget的语句为: if (actionMasked == MotionEvent.ACTION_DO ...

  4. Android Touch事件之二:dispatchTouchEvent()和onTouchEvent()篇

    2015-12-01 15:06:14 Android Touch事件第一篇:Touch事件在父ViewGroup和子View之间的传递简单分析了事件的传递流程,这次深入了解下dispatchTouc ...

  5. 关于dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的分发机制浅析

    虽说这个问题不是很难...动动手就能看出答案...但是似乎不太容易理解...几次尝试把这个问题说明白....但是好像感觉说不明白....(顿时想起了那句话----说不明白就是自己还不明白! 我怎么可能 ...

  6. python方法中的self

    前几天在写一个c作业时,突发奇想,在结构体中加入函数指针, 像这样: struct People { int _age; int (*age)(); }people; 这样调用时就可以 people. ...

  7. 解决webkit浏览器中js方法中使用window.event提示未定义的问题

    这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...

  8. Don’t Use Accessor Methods in Initializer Methods and dealloc 【初始化和dealloc方法中不要调用属性的存取方法,而要直接调用 _实例变量】

    1.问题:    在dealloc方法中使用[self.xxx release]和[xxx release]的区别? 用Xcode的Analyze分析我的Project,会列出一堆如下的提示:Inco ...

  9. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

随机推荐

  1. appium界面运行过程(结合日志截图分析)

    appium界面运行过程: 1.启动一个http服务器:127.0.0.1:47232.根据测试代码setUp()进行初始化,在http服务器上建立一个session对象3.开始调用adb,找到连接上 ...

  2. mybatis 于 hibernate区别

    两者区别是还是非常大的,结合至今为止的经验,总结出以下几点: 1. hibernate是全自动,而mybatis是半自动. hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的Ja ...

  3. Android 本地播放器

    发布时间:2018-09-06   技术:Glide+pinyin4j+SwipeDelMenuLayout   概述 这是一款Android 端的本地音乐播放器,界面风格有模仿网易云音乐.bilib ...

  4. Oracle 9i 10g 11g 区别的转载

    下面看看9i.10g.11g版本的区别 Oracle 10g比9i多的新特性?        1. 10g支持网格计算,即多台结点服务器利用高速网络组成一个虚拟的高性能服务器,负载在整个 网格中衡(L ...

  5. POST、GET请求中文参数乱码问题

    POST请求中文乱码问题解决方法: 在web.xml文件中添加编码过滤器,如下: <!-- 解决post乱码 --> <filter> <filter-name>C ...

  6. Rot13加密算法

    Rot13是一种非常简单的替换加密算法,只能加密26个英语字母.方法是:把每个字母用其后第13个字母代替. 因为有26个字母,取其一半13. s = "xrlvf23xfqwsxsqf&qu ...

  7. binary search tree study

    今天又写了delete的部分,时间就这么被一天天地浪费了,我感到十分惋惜呀 #pragma once #include "stdio.h" struct Node { Node(i ...

  8. find -exec 与xargs 区别

    find . -name "*.txt" -exec rm {} \;find . -name "*.txt" | xargs rm {} -exec    1 ...

  9. HDU 4540 威威猫系列故事——打地鼠 (状态压缩DP)

    威威猫系列故事——打地鼠 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  10. 如何在windows下安装JDK

    1:卸载 A:一定要删除注册表中的 HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft 项 B:最好用安装工具卸载JDK,如果没有的话就删除JDK文件夹然后用Wise Regis ...