Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解

onInterceptTouchEvent用於改變事件的傳遞方向。決定傳遞方向的是返回值,返回爲false時事件會傳遞給子控件,返回值爲true時事件會傳遞給當前控件的onTouchEvent(),這就是所謂的Intercept(攔截)。

[tisa ps:正確的使用方法是,在此方法內僅判斷事件是否需要攔截,然後返回。即便需要攔截也應該直接返回true,然後由onTouchEvent方法進行處理。]

    onTouchEvent用於處理事件,返回值決定當前控件是否消費(consume)了這個事件。尤其對於ACTION_DOWN事件,返回true,表示我想要處理後續事件;返回false,表示不關心此事件,並返回由父類進行處理。

    可能你要問是否消費了又區別嗎,反正我已經針對事件編寫了處理代碼?答案是有區別!比如ACTION_MOVE或者ACTION_UP發生的前提是一定曾經發生了ACTION_DOWN,如果你沒有消費ACTION_DOWN,那麼系統會認爲ACTION_DOWN沒有發生過,所以ACTION_MOVE或者ACTION_UP就不能被捕獲。

在沒有重寫onInterceptTouchEvent()和onTouchEvent()的情況下(他們的返回值都是false), 對上面這個佈局,MotionEvent事件的傳遞順序如下:

當某個控件的onInterceptTouchEvent()返回值爲true時,就會發生截斷,事件被傳到當前控件的onTouchEvent()。如我們將LayoutView2的onInterceptTouchEvent()返回值爲true,則傳遞流程變成:

 如果我們同時將LayoutView2的onInterceptTouchEvent()和onTouchEvent()設置成true,那麼LayoutView2將消費被傳遞的事件,同時後續事件(如跟着ACTION_DOWN的ACTION_MOVE或者ACTION_UP)會直接傳給LayoutView2的onTouchEvent(),不傳給其他任何控件的任何函數。同時傳遞給子空間一個ACTION_CANCEL事件。傳遞流程變成(圖中沒有畫出ACTION_CANCEL事件):

         

[tisa ps:總體來看, onInterceptTouchEvent是自rootview向下傳遞, onTouchEvent正好相反。]


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章