當乙個事件來臨的時候,會先傳遞給最外層的viewgroup(父view,比如linearlayout,framelayout),如果這個viewgroup沒有去攔截這個事件的話,才會給傳遞給下層的viewgroup或者view。如果被攔截掉的話,它會自己去處理這個事件,這個viewgroup內的子view將就不會受到該事件了。
viewgroup的攔截事件的函式為
1
public
boolean
onintercepttouchevent(motionevent ev)
onintercepttouchevent的引數ev就是乙個觸控事件,可以從ev獲取到事件的座標,型別,當前螢幕上點的個數等。通常自定義繼承viewgroup的控制項的時候都會重寫這個方法,判斷目前需不需要攔截,即返回true還是false。返回true的時候表明事件被該view攔截了,不再往下傳了;否則就繼續往子view傳。那返回true的時候怎麼處理呢?
這就需要ontouchevent():
1
public
boolean
ontouchevent(motionevent ev)
具體怎麼實現就根據實際的需要來了。我們發現他的返回值也是boolean,那返回true或者false的時候會有什麼影響呢?用一張圖來說明:
這個乙個典型的流程,也就是所有的相關方法都返回false的時候,乙個事件先到了linearlayout,它不攔截,然後就往下面跑,到了framelayout上,他又不處理,又傳到了button上,這個時候button返回了false,然後這個事件往上傳,最後沒有人處理。當framelayout的兩個方法返回true的時候會怎樣呢?
framelayout的onintercepttouchevent返回true後,就攔截觸控訊息了,然後交給自己的ontouchevent處理。這裡面的邏輯自己定義就好了,如果這個事件被消費掉了,返回true就可以了,這樣系統就不會接著傳了,事件處理到此為止。
是不是按下,移動,鬆開的流程都是按照這樣處理的呢?答案是否定的。action_down事件的判斷和處理,直接影響到了後續的action_move和action_up,在上面的圖中,framelayout的ontouchevent返回了true,那麼當action_move來到framelayout這一層的時候,就不再需要通過onintercepttouchevent攔截了,直接用ontouchevent處理。如果說乙個action_down從頭到尾都是返回false,那麼後續的action_move和action_up就沒法被感知到了。
多點觸控的時候,會多兩個事件 action_pointer_up和action_pointer_down。當第乙個手指按下的時候,會產生action_down,當第二個手指按下的時候,會產生action_pointer_down,第三個或者更多手指按下的時候,也是action_pointer_down,如果此時有乙個手指離開螢幕,會產生action_pointer_up,當最後乙個手指離開螢幕的時候,才會產生action_up。在整個操作過程中,乙個觸點會始終保持乙個固定的id,方便記錄和處理,比如說在action_move的處理過程中,可以通過motionevent的getx(int pointerindex)來獲取某個點的座標。
Android touch事件傳遞
android的touch事件分發機制,涉及到每一層級的處理和傳遞,比較複雜,本文是在參考以下日誌和android原始碼的基礎上總結的,在此表示感謝 1.touch事件傳遞過程 touch事件經過android核心層的處理,最終會傳遞到activity的dispatchtouchevent方法,由此...
android touch事件解析
android touch事件 乙個簡單的觸控螢幕所經歷的事件 action down action move action move action move.action move action up,即乙個acitondown,多個actionmove,乙個actionup android每個g...
Android Touch事件分發
事件 viewgroup view有子元素 view無子元素 activity 方法功能 public boolean dispatchtouchevent motionevent ev yy ny分發 public boolean onintercepttouchevent motionevent...