View負責android應用的顯示,有很重要的地位,而理解View的事件分發機制是實現高質量自定義View和解決滑動沖突問題的基礎,既是重點,也是難點。 本文首先介紹View事件分發機制的流程,然后總結出View事件分發機制的一些結論,最后分析源碼知道這些結論是怎么總結來的。
所謂點擊事件的事件分發,其實就是對MotionEvent事件的分發過程。當手指點擊屏幕時,就會產生一個MotionEvent,然后系統需要把這個事件傳遞給一個具體的View,這個傳遞的過程,就是事件分發。 事件分發流程: 首先,系統會將事件分發給Activity的dispatchTouchEvent(ev)方法,在dispatchTouchEvent(ev)方法中,默認實現下,Activity會把事件分發給Window,Window再把事件分發給DectorView,DectorView接著把事件分發給頂層View,頂層View接著把事件分發給各級子View。如果有View消費了事件,dispatchTouchEvent(ev)會返回true并返回,表示已消費了事件。如果沒有View消費事件,dispatchTouchEvent(ev)方法會把事件傳遞給Activity的onTouchEvent(ev)方法。如果重寫dispatchTouchEvent(ev)方法并返回true或false,事件就不再傳遞給Window及各級View,而直接在Activity的dispatchTouchEvent(ev)中消費。 如果事件傳遞給了ViewGroup,就會調用它的dispatchTouchEvent(ev)方法。默認實現下,它會詢問自身的onInterceptTouchEvent(ev)方法是否攔截事件。如果攔截,首先,它會查看是否設置有touchListener,如果設置有,就調用onTouch(ev)方法,如果onTouch(ev)方法返回true,表示已消費事件,它就返回true,表示事件已在本ViewGroup消費,如果onTouch(ev)方法返回false,它就調用自身的onTouchEvent(ev)方法消費事件。如果不攔截,它就把事件傳遞給子View的dispatchTouchEvent(ev)方法。如果重寫dispatchTouchEvent(ev)并返回true,表示直接在這個方法中消費事件,事件不再傳遞。如果重寫并返回false,表示不在本View及子View中消費事件,事件會返回給上級,一般情況下,上級會在dispatchTouchEvent(ev)方法中把事件傳遞給onTouchEvent(ev)處理。 如果事件傳遞給了View,就會調用它的dispatchTouchEvent(ev)方法。默認情況下,它會查看是否設置有touchListener,如果設置有,就調用onTouch(ev)方法,之后與ViewGroup相同,如果onTouch(ev)返回true,就不調用onTouchEvent,如果返回false,就調用。如果重寫dispatchTouchEvent(ev)并返回true,表示直接在這個方法中消費事件,事件不再傳遞。如果重寫并返回false,表示不在本View中消費事件,事件會返回給上級,一般情況下,上級會在dispatchTouchEvent(ev)方法中把事件傳遞給onTouchEvent(ev)處理。 當事件傳遞給View或ViewGroup的onTouchEvent時,如果返回true,表示事件在這里消費,事件停止傳遞,如果返回false或super,表示事件不在這里消費,事件會被返回給上級處理。super中的默認實現會在ACTION_UP事件發生時會調用performClick,在這個方法中會檢查是否設置有點擊事件監聽器,如果設置有,就會調用onClick事件。 事件分發流程圖如下: 



新聞熱點
疑難解答