Android事件拦截机制

事件拦截

主要是View的onInterceptTouchEvent()方法对touch事件进行拦截。
onInterceptTouchEvent:Touch事件拦截方法

图示:

从外到里的View包含关系依次为:A->B->C->D

(1)onInterceptTouchEvent()方法对touch事件进行拦截,对于嵌套的View,最先执行的是最外层View的onInterceptTouchEvent()方法。然后依次执行子视图的onInterceptTouchEvent()方法,子视图的子视图的onInterceptTouchEvent()方法。(这里假设所有嵌套视图的onInterceptTouchEvent都会得到执行,即每一个View的onInterceptTouchEvent方法返回都为false的情况)

参照上图,事件拦截顺序:onInterceptTouchEvent执行顺序依次为:A->B->C->D,也就是父视图向子视图传递。

总之,事件拦截机制是由父视图开始发起对事件的拦截(出事了老子先上,儿子稍后)。参照上图当手指触摸事件时,父视图A首先发起对该起事件的拦截,如果A拦截失败,就交给它的子视图B进行拦截;如果B拦截失败就交给B的子视图C再进行拦截..直到某一子视图对该次事件拦截成功。

(2)某一视图拦截事件成功与否的判断标识是onInterceptTouchEvent方法的返回值,当返回true的时候说明拦截成功,返回false的时候说明当前视图对事件拦截失败。

也就是说,只有当父视图的onInterceptTouchEvent返回为false时,事件才向子视图onInterceptTouchEvent传递。返回为true时,表示事件拦截成功,不再向下传递,事件交由该View的onTouchEvent方法来处理。子视图的onInterceptTouchEvent不会执行。

(3)拦截成功情况

视图C对当前的touch事件拦截成功:此时意味着C的onInterceptTouchEvent方法返回true,事件将不再向D进行传递。事件拦截成功后,紧接着需要对拦截的事件进行处理,由视图C的onTouchEvent方法来执行。这是不是就意味着当前touch事件是由C视图的onTouchEvent方法来处理的呢?

这要由C视图的onTouchEvent方法的返回值来决定。当C视图的onTouchEvent返回true的时候,当前事件就由C全权处理。

处理的当然是事件的各种action,什么MotionEvent.ACTION_MOVE,ACTION_UP都交给了C的onTouchEvent方法进行处理。所以此时就可以在C的onTouchEvent方法中进行switch(event.getAction)判断执行相关逻辑了。

如果返回的false,说明C视图对此事件不做处理或者处理不了,怎么办呢?儿子不行老爸来,于是事件就交到了B视图的onTouchEvent方法中。同样B对此事件处理与否还是看B的onTouchEvent返回值,具体的解释就跟C一样了,不复多言。

(4)拦截失败情况

如上图,在A B C D的onInterceptTouchEvent和onTouchEvent都返回false的情况下,方法执行的顺序依次为A.onInterceptTouchEvent-->B.onInterceptTouchEvent-->C.onInterceptTouchEvent-->D.touchEvent(最深的子视图没重写onInterceptTouchEvent)-->C.touchEvent-->B.touchEvent-->A.touchEvent.

也就是说拦截事件是父视图优先有子视图进行拦截,处理事件是子视图优先父视图进行处理。

总结:onInterceptTouchEvent负责对事件进行拦截,拦截成功后交给最先遇到onTouchEvent返回true的那个view进行处理。


图解:

一、onInterceptTouchEvent方法返回值情况(此时默认每个onTouchEvent都返回false)

(1)所有ABCD视图都对该事件不拦截和不处理的情况,当传递到最末端的子视图D时对touch事件进行处理,之后事件处理向父视图传递。(默认叶子View是没有onInterceptTouchEvent方法的,只有onTouchEvent事件进行事件处理),也就是所有的onIntercetpTouchEvent方法和onTouchEvent方法都返回false值。
(2)A视图的onInterceptTouchEvent方法对事件进行了拦截,即返回true,则:事件不再向子视图传递,此时由A的onTouchEvent方法进行事件处理。
(3)只有B的onInterceptTouchEvent方法对事件进行了拦截,即返回true,则:事件不再向子视图传递,此时由B的onTouchEvent方法进行事件处理。若此时B视图的onTouchEvent方法返回false,则事件向B的父视图A传递。
(4)同理,只有C的onInterceptTouchEvent方法对事件进行了拦截,即返回true,则:事件不再向子视图传递,此时由C的onTouchEvent方法进行事件处理。若此时C视图的onTouchEvent方法返回false,则事件向C的父视图B传递。

二、onTouchEvent方法返回值情况(此时默认每个onInterceptTouchEvent都返回false,对事件不拦截)

(1)当D的onTouchEvent方法返回true,则表明D对该touch事件全权处理,事件不再向父视图传递。
img
(2)当C的onTouchEvent方法返回true,则表明D处理不了该事件,交由C对该touch事件全权处理,事件不再向父视图B传递。
img

三、dispatchTouchEvent的返回值情况(该方法只有Activity和ViewGroup含有,View不含)

dispatchTouchEvent顾名思义,事件分发

一般事件分发,都是从Activity的DispatchTouchEvent收到触摸事件的Action_down的时候,再将事件分发给ViewGroup的DispatchTouchEvent的。(事件都是从ACTION_DOWN开始的,Activity的dispatchTouchEvent()首先接收到ACTION_DOWN,执行super.dispatchTouchEvent(ev),事件向下分发。)

dispatchTouchEvent()返回true,后续事件(ACTION_MOVE、ACTION_UP)会再传递,如果返回false,dispatchTouchEvent()就接收不到ACTION_UP、ACTION_MOVE。

(1)ACTION_DOWN都没被消费
(2)a、ACTION_DOWN被View消费了
b、后续ACTION_MOVE和UP在不被拦截的情况下都会去找VIEW
(3)后续的被拦截了

Touch事件

android中的Touch事件都是从ACTION_DOWN开始的:
单手指操作:ACTION_DOWN -> ACTION_MOVE -> ACTION_UP
多手指操作:ACTION_DOWN -> ACTION_POINTER_DOWN -> ACTION_MOVE -> ACTION_POINTER_UP -> ACTION_UP.

参考文章:
https://blog.csdn.net/chunqiuwei/article/details/41084921
//www.greatytc.com/p/9f521f34386a
https://blog.csdn.net/xyz_lmn/article/details/12517911

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345