一.不知道你是否在涉及到Android觸屏事件的時候有過如下的疑問:
1.View的onTouchEvent()方法返回true和false有什麼區別? SDK給出的解釋很簡單:"返回true代表該事件已經被處理過了,返回false則相反",這句話完全沒有解釋清楚問題。
2.View的onTouchEvent()方法在處理ACTION_DOWN的時候返回true,在處理ACTION_MOVE的時候返回false,代表著是處理了還是沒處理?返回super.onTouchEvent()又是什麼含義?
3.重寫onTouchEvent()方法和通過setOnTouchListener()設置一個觸屏監聽有什麼區別,看起來好像很類似。
4.View的dispatchTouchEvent(),onTouchEvent(),setOnClickListener(),ViewGroup的onInterceptTouchEvent()把我繞暈了,這些方法怎麼使用怎麼重寫?
5.假設一個ViewGroup有兩個子view,這兩個view有一部分是重疊的,點擊該重疊部分,事件由哪個View來處理?
6.最重要的一點疑問是:觸屏事件從頂層ViewGroup一直向下是怎麼傳遞的?
如果你有類似的疑問,相信我的這篇博客能給你答案。
二.首先需要明確的幾點是:
1.View一般是為了顯示某些內容而存在的,它也通常用來處理用戶的觸屏等交互事件,而ViewGroup則是做為View的容器而存在的,雖然在代碼上它是View的子類,但它通常只是做為容器用來組織它的子視圖布局方式。
2.我們知道android裡邊View層次是一種樹型結構,需要明確的是一個ViewGroup它的直接子視圖才算是樹結構中的兒子,再往下一層就不算了,類似於進程間的父子關系。舉例,FrameLayout有兩個子視圖,分別是LinearLayout和TextView,而LinearLayout又有三個子視圖ImageView,那麼調用FrameLayout的getChildCount()方法只會返回2,而不是5。因此以下內容中"子視圖"這個術語代表著一個ViewGroup的直接子視圖,它即可能是一個View類,也可能是一個ViewGroup類。
3.Activity視圖的最頂層View是DecorView,它是在PhoneWindow類中通過generateDecor()方法生成的,它繼承自FrameLayout,是View層次的根視圖。
4.對於觸屏來說有三個主要的事件:down,move,up
那麼一個觸屏事件到底是怎麼在View層次中上向下傳遞的?(這裡只考慮事件已經到達DecorView時的情形,事實上是ViewRootImpl類接收到底層InputDispatch傳遞過來的事件,這裡就不寫了),ViewRootImpl在deliverPointerEvent()方法中通過調用mView.dispatchPointerEvent(event);將觸屏事件傳遞給了DecorView,DecorView通過dispatchTouchEvent()繼續向下傳遞給子視圖,如果子視圖也是一個ViewGroup,它又會調用自己的dispatchTouchEvent()方法向下傳遞,如果子視圖是一個View,那麼子視圖的onTouchEvent()方法就會被調用,如果子視圖處理了該事件,那麼事件傳遞就中止。整個過程像是一個遞歸過程,理解了一個ViewGroup怎麼通過dispatchTouchEvent()傳遞給它的子視圖這一層也就理解了整個過程。
這裡就不分析ViewGroup的dispatchTouchEvent()方法的代碼了,直接給出我總結出來的結論,有興趣的讀者可以分析看看。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-12/93387p2.htm