寫一遍加深記憶 Android的事件分發處理流程

2021-07-24 19:46:09 字數 2777 閱讀 5530

onintercepttouchevent()與ontouchevent()的機制:  

1. down事件首先會傳遞到onintercepttouchevent()方法  

2. 如果該viewgroup的onintercepttouchevent()在接收到down事件處理完成之return

false,那麼後續的move, up等事件將繼續會先傳遞給該viewgroup,之後才和down事件一樣傳遞給最終的目標view的ontouchevent()處理  

3. 如果該viewgroup的onintercepttouchevent()在接收到down事件處理完成之後return

true,那麼後續的move, up等事件將不再傳遞給onintercepttouchevent(),而是和down事件一樣傳遞給該viewgroup的ontouchevent()處理,注意,目標view將接收不到任何事件。  

4. 如果最終需要處理事件的view的ontouchevent()返回了false,那麼該事件將被傳遞至其上一層次的view的ontouchevent()處理  

5. 如果最終需要處理事件的view 的ontouchevent()返回了true,那麼後續事件將可以繼續傳遞給該view的ontouchevent()處理。

以上官方解釋,標準

對於安卓的事件分發,我理解如下觀點

viewgroup 有 dispatchtouchevent、onintercepttouchevent、ontouchevent

view  只有 dispatchtouchevent、ontouchevent,因為 onintercepttouchevent是viewgroup 的函式

假如a viewgroup,包含view b,那麼一次預設正常的按下事件執行流程如下

a dispatchtouchevent》a  onintercepttouchevent》b dispatchtouchevent 》b ontouchevent ,

其實 dispatchtouchevent 的 super.dispatchtouchevent(ev) 特別關鍵,因為他是呼叫該類的  onintercepttouchevent、ontouchevent 方法。

由此可見,真實的 按下事件流程如何: a (super前)dispatchtouchevent》a  onintercepttouchevent》b (super前)dispatchtouchevent 》b ontouchevent 》b (super 後)dispatchtouchevent 》a (super後)dispatchtouchevent。

預設情況下,就是a類 對事件不作任何修改

如果在 b類中事件也沒處理,就是均是false, 這個時候父類即入口的 super.dispatchtouchevent 就是false,於是對於鬆手up\move 等 事件,就不會繼續給該控制項了,因為他的dispatchtouchevent 返回false,(意思就是我不需要你這些觸控事件了)

如果b的 dispatchtouchevent 返回true,就是說 你的事件我有關注,我需要觸控事件,於是up 、move  都會接受,對於b類 什麼時候會返回true呢?ontouchevent 事件返回true,和人為地dispatchtouchevent返回true 均可。事件都會傳遞到 dispatchtouchevent中,當然是否傳遞到 ontouchevent 還需要靠super.dispatchtouchevent的呼叫。只要b中的dispatchtouchevent 返回true,都是說明b 需要關注事件的。

如果b dispatchtouchevent 返回true ,那麼對於a dispatchtouchevent 就是也就會是返回true,就是說明這次activity的事件,這個元件有處理;

對於a類

ontouchevent 方法時候呼叫呢?前提是 dispatchtouchevent 中的super.dispatchtouchevent有執行,不過還需要 onintercepttouchevent 方法返回true 來攔截給該view 處理,不然會傳遞到下乙個子view的,如果此時子view ontouchevent 返回false,不處理事件,那麼也會呼叫父控制項的 ontouchevent 方法;

如果a類 onintercepttouchevent 攔截了事件,那麼b類就不會收到如何事件傳遞, 那攔截了誰來處理呢?當然是a的ontouchevent 方法,如果ontouchevent 返回true,說明消費了該事件,於是a的dispatchtouchevent 就會返回true,給上層說有關注了該觸控事件,如果 攔截了,但是 ontouchevent  卻返回false,說明了 a只是攔截了事件,卻對事件不感興趣或者不符合a的要求事件,於是 super.dispatchtouchevent 會返回false。於是 後續的up、move均不傳遞進來a ;

結論dispatchtouchevent 方法是乙個分發的意思,並且裡面的super.dispatchtouchevent 是會執行onintercepttouchevent、ontouchevent方法 和子view 的dispatchtouchevent 等。如果這個函式返回true,說明有控制項關注這個事件,自身或者是 子view,於是後續的事件up、move 就會傳遞過來;否則就不接受後續事件了;

onintercepttouchevent 只是viewgroup 的攔截方法,但是是否消費是在ontouchevent 中,viewgroup必須先攔截才有消費的可能,如果當前viewgroup攔截並處理了,對於後續的up、move事件不再需要攔截,但是父viewgroup流程繼續走;

view 中的消費也是ontouchevent ,因為他沒子view,所以不需要攔截,只需要判斷是非消費即可

記憶一遍一遍,總是牽扯著已經過去的過去

qq個性簽名 記憶一遍一遍,總是牽扯著已經過去的過去.白紙上寫滿了你的名字 忍不了痛苦,就見不到幸福 愛情是壹個精心設計的謊言 我微笑時,是因為我想妳了 笑容背後總有與之相反的傷 壹句對不起,不足以被原諒 壹曲醉生夢死壹場酣暢淋漓 想說太多,又不知從何說起 愛恨放在心裡眼裡,曬出溫暖 我討厭不安和懷...

再一遍的執行力

記bill老師的第一堂乾貨,絕對要分享的啊!重讀 知道 做到 why how 1 消極過濾 綠燈思維 2 資訊過載 少而精 專注和重複 3 缺少跟進 目標和重複 bill為什麼這麼厲害?why me?集體利益最大化,先是集體利益,再是個人利益。正如我為人 人,人人為我!why that?執行力!怎樣...

只學一遍的策略模式

策略模式屬於物件的行為模式。其用意是針對一組演算法,將每乙個演算法封裝到具有共同介面的對立的類中,從而使得她們可以相互替換。策略模式使得演算法可以在不影響到客戶端的情況下 策略模式的結構 環境 context 角色 持有乙個strategy的引用。抽象策略 strategy 角色 這是乙個抽象角色,...