Android事件傳遞屬於老生長談的知識點,很多人知道其中的原理,可真的要表述出來還是有些遺漏。自己也曾複習過這些,沒有留下書面記錄,時間長了就忘了,所以記錄下。
1. 事件傳遞對象:window activity viewGroup view;
2. 事件分發的原理:
(1)首先由Activity分發,分發給根View,也就是DecorView(DecorView爲整個Window界面的最頂層View)
(2)然後由根View分發到子的View;
3. 事件分發流程:
activity從父類拿到事件後,默認會按照以下流程進行事件傳遞:
整個事件流向從Activity---->ViewGroup--->View 從上往下調用dispatchTouchEvent方法,一直到葉子節點(View)的時候,再由View--->ViewGroup--->Activity從下往上調用onTouchEvent方法。
子View中如果將傳遞的事件消費掉,父類的ViewGroup中將無法接收到任何事件。該事件的傳遞流程如下圖:
4. 事件分發的幾個處理方法:
ViewGroup的事件傳遞方法:
dispatchTouchEvent
onInterceptTouchEvent
onTouchEvent
View的事件傳遞方法:
View的dispatchTouchEvent
View的onTouchEvent
dispatchTouchEvent 作用:
首先看下ViewGroup 的dispatchTouchEvent,return true是終結傳遞。return false 是回溯到父View的onTouchEvent,然後ViewGroup怎樣通過dispatchTouchEvent方法能把事件分發到自己的onTouchEvent處理呢,return true和false 都不行,那麼只能通過Interceptor把事件攔截下來給自己的onTouchEvent,所以ViewGroup
dispatchTouchEvent方法的super默認實現就是去調用onInterceptTouchEvent,記住這一點。
那麼對於View的dispatchTouchEvent return super.dispatchTouchEvent()的時候呢事件會傳到哪裏呢,很遺憾View沒有攔截器。但是同樣的道理return true是終結。return false 是回溯會父類的onTouchEvent,怎樣把事件分發給自己的onTouchEvent 處理呢,那隻能return super.dispatchTouchEvent,View類的dispatchTouchEvent()方法默認實現就是能幫你調用View自己的onTouchEvent方法的。
onInterceptTouchEvent作用:
Intercept 的意思就攔截,每個ViewGroup每次在做分發的時候,問一問攔截器要不要攔截(也就是問問自己這個事件要不要自己來處理)如果要自己處理那就在onInterceptTouchEvent方法中 return true就會交給自己的onTouchEvent的處理,如果不攔截就是繼續往子控件往下傳。
默認是不會去攔截的,因爲子View也需要這個事件,所以onInterceptTouchEvent攔截器return super.onInterceptTouchEvent()和return false是一樣的,是不會攔截的,事件會繼續往子View的dispatchTouchEvent傳遞。
onTouchEvent作用:
做事件處理
1、自己消費掉,事件終結,不再傳給誰----->return true;
2、繼續從下往上傳,不消費事件,讓父View也能收到到這個事件----->return false;View的默認實現是不消費的。所以super==false。
5. 注意down 事件跟move up 的傳遞不太一樣
(1)一切事件處理的開始都是從Down事件開始的,如何你處理了Down事件,其他的事件就都收不到了。
(2)onTouch事件、onLongClick事件、onClick事件默認是同時執行:(執行的先後順序:onTouch > onLongClick > onClick)