1. 程式人生 > >"Android Touch事件分發機制"-Android面試必問"精華技能點"彙總

"Android Touch事件分發機制"-Android面試必問"精華技能點"彙總

目錄:

一.事件分發中的 onTouch 和 onTouchEvent 有什麼區別,又該如何使用?

1.onTouch方法:

  • 是View的 OnTouchListener介面中定義的方法。
  • 當一個View綁定了OnTouchLister後,當有touch事件觸發時,就會呼叫onTouch方法。

2.onTouchEvent方法:

  • 是override 覆蓋Activity的方法。
  • 當螢幕有touch事件時,此方法就會別調用。

3.touch事件的傳遞:

(PS:onTouch 優先於 onTouchEvent 執行,兩者都能得到事件內容(下,移動,彈起))

  • 1.Activity有放一個TextView的例項tv,觸控時首先是tv響應touch事件,執行onTouch方法
  • 2.如果onTouch返回值為true,表示這個touch事件被onTouch方法處理完畢,不會把touch事件再傳遞給Activity,onTouchEvent方法不會被呼叫。

  • 3.返回false,表示這個touch事件沒有被tv完全處理,onTouch返回以後,touch事件被傳遞給Activity,onTouchEvent方法被呼叫。

  • 4.這兩個方法都是在 View 的 dispatchTouchEvent 中呼叫.

  • 5.控制元件必須是enable的,否則onTouch事件將永遠得不到執行。

二.請描述一下 Android 的事件分發機制

主角:主要有兩個:ViewGroup 和 View。

  • Activity 的 Touch事件事實上是呼叫它內部的ViewGroup的Touch事件.

  • View 在ViewGroup內,ViewGroup 也可以在其他ViewGroup內,這時候把內部的ViewGroup當成View 來
    分析。

  • 先分析ViewGroup 的處理流程:首先得有個結構模型概念:ViewGroup和View組成了一棵樹形結構,最頂層為 Activity 的 ViewGroup,如圖:
    這裡寫圖片描述

  • 當一個 Touch 事件(觸控事件為例)到達根節點,即Acitivty 的ViewGroup 時,它會依次下發,下發的過程是呼叫子View(ViewGroup)的dispatchTouchEvent方法實現的。

  • 簡單來說,就是ViewGroup遍歷它包含著的子View,呼叫每個 View 的 dispatchTouchEvent 方法.
  • 而當子 View 為 ViewGroup 時,又會通過呼叫 ViwGroup 的dispatchTouchEvent方法繼續呼叫其內部的View 的dispatchTouchEvent方法。
  • 上述例子中的訊息下發順序是: ①-②-⑥-⑦-⑧-③-④-⑤
  • 如果⑥的dispatchTouchEvent返回結果為true,那麼⑥-⑦-③-④將都接收不到本次Touch事件。
  • (PS:一般預設是false不操作這個分發的方法)

關於Down,Move,Up:

  • 1.觸控事件由Action_Down、Action_Move、Aciton_UP 組成,其中一次完整的觸控事件中,Down和Up 都只有一個,Move有若干個,可以為0個。
  • 2.當Acitivty 接收到 Touch事件時,將遍歷子 View 進行 Down 事件的分發。ViewGroup 的遍歷可以看成是遞迴的。分發的目的是為了找到真正要處理本次完整觸控事件的 View。

  • 3.當某個子View 的onTouchEvent()返回true時,會中止Down 事件的分發,同時在ViewGroup中記錄該子View。接下去的Move和Up 事件將由該子View 直接進行處理。

  • 4.由於子View 是儲存在ViewGroup中的,多層ViewGroup的節點結構時,上級ViewGroup儲存的會是真實處理事件的View所在的ViewGroup物件:如ViewGroup0-ViewGroup1-TextView的結構中,TextView 返回了 true,它將被儲存在 ViewGroup1 中,而 ViewGroup1 也會返回 true,被儲存在ViewGroup0中。當Move和UP事件來時,會先從ViewGroup0傳遞至ViewGroup1,再由ViewGroup1 傳遞至TextView。

  • 6.當ViewGroup 中所有子View 都不捕獲Down 事件時,將觸發ViewGroup自身的onTouch事件。觸發的方式是呼叫super.dispatchTouchEvent函式,即父類View 的dispatchTouchEvent方法。在所有子View 都不處理的情況下,觸發Acitivity的onTouchEvent方法。

  • 7.onInterceptTouchEvent有兩個作用:

    • 1.攔截Down 事件的分發。
    • 2.中止Up 和Move事件向目標View 傳遞,使得目標View所在的ViewGroup捕獲Up和Move事件。

三.程式碼演示

佈局程式碼如下:
這裡寫圖片描述
效果圖:
這裡寫圖片描述
三個程式碼都寫onTouch方法
這裡寫圖片描述
各自點選內,中外,效果圖如下:
這裡寫圖片描述
分別各自測試逐個設定消費的情況(觀察列印才次數,摁下和彈起),列印的效果:
這裡寫圖片描述

得出結論一:
這裡寫圖片描述

  • 然後重寫方法:
    • 佈局重寫分發方法和攔截方法
    • view重寫分發方法
      這裡寫圖片描述

然後再分別測試他們的傳遞過程:
這裡寫圖片描述