1. 程式人生 > >Android面試題(27)-android的事件分發機制

Android面試題(27)-android的事件分發機制

今天開始寫一點關於view的知識,先從最基本的講吧,android的事件分發機制,其實在我看來,android的事件分發機制在現實生活中經常能看到,所以我覺得還是很好理解的;

先看看生活中常見的一種情形吧;

比如說,現在你所在的公司中有一項任務被派發下來了,專案經理把專案交給你的老大,你的老大老大手下有很多人,看了看覺得你做很合適,把這個任務交給你了;你一看覺得還行,你就接下來了;

這麼一個小小場景大概就說明了android的事件分發;簡而言之,就是大的傳小的,小的能處理就處理,處理不了再返回給大的;

好,現在具體看看事件分發;

首先我們先看看為什麼會有事件分發機制:

我們知道,android上的View是樹形結構的,View可能會重疊在一起,當我們點選的地方有多個View都可以響應的時候,這個點選事件應該給誰呢?事件分發機制就是為了處理這個問題的;

接下來看看關於事件分發的三個主要物件:

一個事件產生之後,都是先傳給Activity,在傳給ViewGroup,最後傳給View,對比上面的例子,Activity對應的就是專案經理,viewGroup就是你的老大,而你就相當於view了;

三個重要方法:

這裡要注意一點,Activity和View是沒有onInterceptTouchEvent()也就是事件攔截這個方法的,仔細想想就可以想明白,Activity是處於分發機制的最頂端,如果一開始就吧事件攔截了,那麼會導致整個螢幕都無法響應使用者的操作,這就相當於一個專案裡所有的事情都由你的專案經理一個人幹了,這顯然是不理智的;而view處於事件分發的最末端,它不需要攔截,事件分發到View的時候,view能處理就處理,不處理就返回給他的父控制元件;

事件分發流程:

在講上面這個圖之前呢,我先解釋一下這個phonewindow和decorview

手機螢幕我們可以稱為一個視窗,也就是一個window,在android中這個window類是一個抽象類,它規定了一些管理視窗的方法,但是具體實現是由它的唯一實現類phonewindow去實現的,這樣phonewindow就是整個螢幕的實際“掌控者”,而phonewindow又是通過它的內部類decorview去對view進行管理;

接下來進行流程分析,我們就以點選事件為例:

當用戶點選了螢幕,首先Activity先監測到,事件先傳遞到Activity中,Activity通過它的dispatchTouchEvent將事件分發到phoneWindow,phonewindow則會呼叫superdispatchTouchEvent方法的內部是呼叫了其內部類DecorView的superdispatchTouchEvent,而DecorView又會呼叫dispatchTouchEvent去進行事件分發,如果不攔截事件,那麼就會繼續下傳到rootview,rootview中的操作是一樣的,同樣在dispatchTouchEvent內部呼叫onInterceptTouchEvent去判斷是否攔截,不攔截就會把事件分發給下一個viewgroupA,攔截就直接在onTouchEvent返回true,viewgroupA中做的判斷也是一樣,最後事件傳遞到view1,view1是最底層控制元件,不會有onInterceptTouchEvent,它的選擇就只有處理後不處理,處理就在onTouchEvent進行處理並返回true,不處理的話事件也不會被銷燬,view1這時會把事件回傳,經過上述流程後回傳給activity,如果Activity還不處理,那麼這個事件才會被銷燬;

讀懂上面的敘述,相信對android的事件分發有很清晰的認識了;