Android中觸控事件的傳遞機制

weixin_34321977發表於2018-05-16
  • 觸控事件的型別

    Android中觸控事件對應的類是MotionEvent類,事件的型別主要有如下三種情況
    ACTION_DOWN:使用者手指的按下操作,一個按下事件標誌著一個觸控事件的開始
    ACTION_MOVE:使用者手指按壓螢幕後,鬆開之前,如果移動的距離超過一定的閾值,那麼會被判定為ACTION_MOVE操作,一般情況下手指輕微移動都會出發一系列的操作
    ACTION_UP:使用者手指離開螢幕的操作,一次抬起標誌著該事件的結束

  • 事件傳遞的三個階段
    分發:在Android中所有的事件分發對應著dispatchTouchEvent方法


    2396043-66af8db86446e90c.png
    QQ截圖20180516213123.png

    在這個方法中,根據當前檢視的具體實現邏輯,來決定直接消費掉這個事件還是將該事件繼續分發給子檢視進行處理,方法返回值為true,表示事件被當前檢視消費掉,不再繼續分發事件,方法返回值為super.dispatchTouchEvent()則表示繼續分發該事件,如果當前檢視是ViewGroup及其子類,會呼叫onInterceptTouchEvent()方法來判定是否攔截該事件
    攔截:事件的攔截對應著onInterceptTouchEvent(),此方法只在ViewGroup及其子類才有,Activity與View中是沒有該方法的


    2396043-cedfa91385311b76.png
    QQ截圖20180516214119.png

    同理:該方法返回true,表示攔截該事件,不繼續分發給子檢視,同時交由自身的onTouchEvent()進行消費,返回super.onInterceptTouchEvent()表示不攔截該事件,需要繼續傳遞給子檢視
    消費:事件的消費對應著onTouchEvent()方法
2396043-9cef9d062b133e48.png
QQ截圖20180516214533.png

同理:該方法返回true,表示當前檢視可以處理該事件,事件將不會向上傳遞給福檢視,返回false表示當前檢視不處理該事件,事件將會傳遞給父檢視的onTouchEven()進行處理

經測試,我們得出以下結論

View的事件分發

從上面的結論可以得出,View事件的傳遞只關乎分發和消費,並沒有攔截的功能,那麼兩個方法的返回值有可能存在以下三種情況
直接返回true
直接返回false
或者返回父類的同名方法

  • 觸控事件的傳遞流程是從dispatchTouchEvent()開始的,如果不進行人為的干預(也就是所預設返回父類的同名函式),則事件將會依照巢狀的層次從外層想內層傳遞,到達最內層的view時,就由它的onTouchEvent()進行處理,該方法能夠消費該事件,返回true,不能消費,則返回false,這時事件將會重新向外層傳遞,並由外層的onTouchEvent()進行處,以此類推
  • 如果事件在內層傳遞過程中進行人為干預,事件處理的函式返回true,則會導致事件提前被消費掉,內層的view將不會收到該事件。
  • View控制元件的事件觸發順序是先執行onTouch(),再最後執行onClick(),如果onTouch()返回true,則事件不會繼續傳遞,最後也不會呼叫onClick(),如果onTouch()返回false,則該事件繼續傳遞
ViewGroup的事件分發
  • 觸控事件的傳遞順序是由Activity到ViewGroup,再由ViewGroup遞迴傳遞給它的子view,
  • ViewGroup通過onInterceptTouchEvent()對事件進行攔截,如果該方法返回true,則事件不會被繼續傳遞,如果返回false或者super.onInterceptTouchEvent,則事件被繼續傳遞給子view。
  • 在子view中事件被消費後,ViewGroup將接受不到任何事件。

相關文章