Android View事件處理

事件的處理對象們

Android中View的事件處理用的是設(shè)計(jì)模式中的職責(zé)鏈模式。整個(gè)職責(zé)鏈中的處理對象是這樣的:Activity->ViewGroup->View澈段。

事件處理的三個(gè)重要階段

這三類事件處理對象對事件的處理主要有三個(gè)階段省有,對應(yīng)三個(gè)重要的方法:

  1. 事件分發(fā):boolean dispatchTouchEvent(MotionEvent ev)
    讓當(dāng)前處理對象決定是由自己來消費(fèi)事件英支,還是將事件交給子View來處理碉哑。Activity度陆、ViewGroup蔽介、View都有這個(gè)方法摘投。
  2. 事件攔截:boolean onInterceptTouchEvent(MotionEvent ev)
    讓處理對象決定要不要繼續(xù)把時(shí)間傳遞給子View,還是自己消費(fèi)掉算了 虹蓄。只有ViewGroup有這個(gè)方法犀呼。
  3. 事件消費(fèi):boolean onTouchEvent(MotionEvent ev)
    決定是否消費(fèi)掉事件,如何消費(fèi)薇组。Activity外臂、ViewGroup、View都有這個(gè)方法律胀。

這三個(gè)方法不同的返回值會影響事件的傳遞宋光,其實(shí)還是挺復(fù)雜的。今天趁著勞動節(jié)累铅,我來做做體力勞動跃须,自定義一個(gè)ViewGroup和一個(gè)View,通過日志打印出這三個(gè)方法在不同的返回值下的調(diào)用娃兽。

onTouchEvent
all onTouchEvent false

viewGroup onTouchEvent true, view onTouchEvent false
  • 返回false或者是super.onTouchEvent時(shí)菇民,表示當(dāng)前View不想消費(fèi)事件。則會逐級調(diào)用其父控件的onTouchEvent方法投储,直到調(diào)用的父控件的onTouchEvent返回true為止第练,即直到有父控件消費(fèi)掉事件為止,或者是最終被Activity消費(fèi)掉事件玛荞。這就是典型的職責(zé)鏈模式
  • 當(dāng)某個(gè)事件在最終被某個(gè)對象的onTouchEvent消費(fèi)掉后娇掏,這個(gè)事件之后連續(xù)的事件都會在分發(fā)到那個(gè)對象后,直接被它的onTouchEvent消費(fèi)掉勋眯,而不會繼續(xù)傳遞給子View了婴梧。從日志當(dāng)中可以看出下梢,View和ViewGroup的onTouchEvent都返回false,不消費(fèi)事件塞蹭,ACTION_DOWN事件最終被Activity消費(fèi)掉孽江。這此后ACTION_UP在被dispatch到Activity之后,就直接調(diào)用Activity的onTouchEvent番电,不會繼續(xù)往下傳遞給子View了岗屏。同樣的,當(dāng)ViewGroup消費(fèi)ACTION_DOWN事件后漱办,接下來的ACTION_MOVE, ACTION_UP都會在dispatch到ViewGroup后这刷,調(diào)用ViewGroup的onTouchEvent
onTouchEvent true
  • onTouchEvent返回true時(shí)娩井,表示當(dāng)前View想要消費(fèi)掉事件暇屋。連續(xù)的所有的事件都會逐層被分發(fā)到當(dāng)前View后,調(diào)用onTouchEvent方法
onInterceptTouchEvent
ViewGroup onInterceptTouchEvent=true, onTouchEvent=true

ViewGroup onInterceptTouchEvent=true, onTouchEvent=false
  • onInterceptTouchEvent返回true時(shí)洞辣,表示當(dāng)前ViewGroup想攔截事件率碾。此時(shí)會調(diào)用ViewGroup的onTouchEvent方法,它的子View會收到ACTION_CANCEL事件屋彪。如果ViewGroup的onTouchEvent返回true,則接下來的事件都會直接交給ViewGroup的onTouchEvent去處理绒尊,不會再調(diào)用onInterceptTouchEvent了畜挥。也就是ViewGroup從某個(gè)點(diǎn)攔截住事件,并且消費(fèi)掉事件后婴谱,就可以直接處理接下來的事件而不需要再次攔截了蟹但。如果ViewGroup的onTouchEvent返回false,那么事件會被逐級向上傳給它的父View的onTouchEvent去處理谭羔,并且此后連續(xù)的事件都不會傳遞給當(dāng)前的ViewGroup了华糖,也就是說當(dāng)前ViewGroup再也沒有機(jī)會收到接下來的事件了。因此瘟裸,一般在自定義ViewGroup時(shí)客叉,onInterceptTouchEvent返回true開始攔截事件時(shí),都要讓onTouchEvent返回true话告,并在onTouchEvent處理接下來的事件兼搏。
ViewGroup onInterceptTouchEvent=false
  • 當(dāng)onInterceptTouchEvent返回false或者super.onInterceptTouchEvent時(shí),表示當(dāng)前ViewGroup不攔截事件沙郭,事件分發(fā)到子View
  • 當(dāng)還沒有確定事件講會被哪個(gè)View處理時(shí)佛呻,事件在分發(fā)階段都會調(diào)用onInterceptTouchEvent,但是一旦事件的處理對象明確后病线,onInterceptTouchEvent講不會再被調(diào)用吓著。這就是為什么鲤嫡,當(dāng)最底層的ViewonTouchEvent返回true消費(fèi)掉事件后,接下來的事件不知道到底會被誰處理绑莺,因此被下發(fā)到底層View的過程中還是會調(diào)用ViewGroup的onInterceptTouchEvent暖眼。而當(dāng)事件被中途攔截,或者會被上層的某個(gè)父View處理后紊撕,ViewGroup的onInterceptTouchEvent都不會被調(diào)用罢荡。
dispatchTouchEvent
Paste_Image.png
  • 返回'true',事件無疾而終对扶,接下來的連續(xù)的事件也無疾而終無人處理区赵。
Paste_Image.png
  • 返回false,事件也不會繼續(xù)往下傳遞浪南,但是會被逐級向上傳遞給父view的onTouchEvent去處理笼才。
  • 返回super.dispatchTouchEvent時(shí),事件才會正常的往下傳遞給子View络凿。一開始學(xué)習(xí)的時(shí)候骡送,我有一個(gè)誤區(qū),認(rèn)為這三個(gè)方法要么返回true絮记,要么返回false摔踱,返回true的時(shí)候是自己處理事件,返回false的時(shí)候是讓子view去處理事件怨愤。其實(shí)不是這樣的派敷,返回true的時(shí)候確實(shí)是讓自己來處理事件,但是必須要調(diào)用super.dispatchTouchEvent才會把事件傳遞給子View進(jìn)行處理撰洗。
  • 參考簡書其它朋友寫的文章

ViewGroup的dispatchTouchEvent是真正在執(zhí)行“分發(fā)”工作篮愉,而View的dispatchTouchEvent方法,并不執(zhí)行分發(fā)工作差导,或者說它分發(fā)的對象就是自己试躏。一般情況下,我們不該在普通View內(nèi)重寫dispatchTouchEvent方法设褐,因?yàn)樗⒉粓?zhí)行分發(fā)邏輯颠蕴。當(dāng)Touch事件到達(dá)View時(shí),我們該做的就是是否在onTouchEvent事件中處理它助析。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裁替,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子貌笨,更是在濱河造成了極大的恐慌弱判,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锥惋,死亡現(xiàn)場離奇詭異昌腰,居然都是意外死亡开伏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門遭商,熙熙樓的掌柜王于貴愁眉苦臉地迎上來固灵,“玉大人,你說我怎么就攤上這事劫流∥撞#” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵祠汇,是天一觀的道長仍秤。 經(jīng)常有香客問我,道長可很,這世上最難降的妖魔是什么诗力? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮我抠,結(jié)果婚禮上苇本,老公的妹妹穿的比我還像新娘。我一直安慰自己菜拓,他們只是感情好瓣窄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著纳鼎,像睡著了一般康栈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喷橙,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音登舞,去河邊找鬼贰逾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛菠秒,可吹牛的內(nèi)容都是我干的疙剑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼践叠,長吁一口氣:“原來是場噩夢啊……” “哼言缤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起禁灼,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤管挟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后弄捕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體僻孝,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡导帝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了穿铆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雀鹃。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遍愿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胳挎,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布伤提,位于F島的核電站题涨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏别洪。R本人自食惡果不足惜叨恨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挖垛。 院中可真熱鬧痒钝,春花似錦、人聲如沸痢毒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哪替。三九已至栋荸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凭舶,已是汗流浹背晌块。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帅霜,地道東北人匆背。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像身冀,于是被迫代替她去往敵國和親钝尸。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容