android事件分發機制詳解

talang發表於2019-03-27

1.事件的定義:

android事件分發機制詳解

2.事件序列

android事件分發機制詳解

3.事件分發的物件

(1)Activity:控制生命週期 & 處理事件

(2)ViewGroup:一組View的集合(含多個子View)

(3)View:所有UI元件的基類

4.事件分發的主要方法

(1)dispatchTouchEvent(MotionEvent ev): 用來進行事件分發;

(2)onInterceptTouchEvent(MotionEvent ev): 判斷是否攔截事件(只存在於ViewGroup             中);

(3)onTouchEvent(MotionEvent ev): 處理點選事件

5.Activity的事件分發:

從activity的dispatchEvent(MotionEvent ev)方法開始進行事件的分發,程式碼如下:

public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction(); //空方法,子類可重寫
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}複製程式碼

我們可以看到activity的dispatchTouchEvent(MotionEvent ev) 方法中呼叫了getWindow().superDispatchTouchEvent()方法。getWindow()就是window的唯一實現類PhoneWindow。所有我們可以接著看PhoneWindow中的superDispatchTouchEvent()方法:

@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);
}複製程式碼

由以上程式碼可以發現PhoneWindow的superDispatchTouchEvent()方法裡面呼叫的是mDecor.superDispatchTouchEvent()方法。mDecor就是視窗的頂層佈局DecorView。DecorView中的super.DispatchTouchEvent()方法最終呼叫的是ViewGroup的的dispatchTouchEvent方法。

以上是activity到ViewGroup的時間分發流程,再來看看activity的dispatchTouchEvent()方法,如果getWindow().superDispatchTouchEvent()方法返回true,表示事件被activity中的子控制元件消費,如果返回false,則會執行activity的onTouchEvent()方法。我們來看看activity的onTouchEvent()方法:

public boolean onTouchEvent(MotionEvent event) {
    if (mWindow.shouldCloseOnTouch(this, event)) { //判斷是否有超出邊界,如果超出,直接finish
        finish();
        return true;
    }

    return false; //如果沒有超出,表示事件沒有被activity消費,事件結束
}
複製程式碼

6.ViewGroup的時間分發

ViewGroup的事件分發dispatchTouchEvent()方法可以用一段虛擬碼來解釋:

android事件分發機制詳解

由上圖我們可以明白:ViewGroup的dispatchTouchEvent()方法中呼叫了onInterceptTouchEvent()方法來判斷是否攔截事件,如果攔截,則呼叫自己的onTouchEvent()方法。如果不攔截,則呼叫子View的dispatchTouchEvent()方法,將事件分發給子View處理。

7.View的事件分發

View的dispatchTouchEvent()事件分發的虛擬碼實現:android事件分發機制詳解

由吸上虛擬碼可以判斷,當View設定了TouchListener的時候,會先呼叫TouchListener的onTouch()方法,如果onTouch()方法返回true,則不會執行View的onTouchEvent()方法,如果返回false才會執行onTouchEvent()方法。TouchListener、onTouchEvent、ClickListener的優先順序是:TouchListener>onTouchEvent>ClickListener.

8.事件分發機制總結

android事件分發機制詳解

上圖介紹了事件分發機制的整體流程:

首先事件分發之後由activity分發到達根佈局ViewGroup,之後會呼叫ViewGroup的dispatchTouchEvent()方法,dispatchTouchEvent()方法中通過呼叫ViewGroup自身的interceptTouchEvent()方法來判斷是否對時間進行攔截,如果攔截,則呼叫自身的onTouchEvent()方法,onTouchEvent()方法判斷是否消費事件,如果消費則事件消費結束,如果不消費,則交給activity的onTouchEvent()方法進行處理;如果不攔截,則事件會交給子View處理,如果子View也是ViewGroup的話,流程跟以上一樣;如果View沒有子View的話,則會呼叫View的dispatchTouchEvent()方法,View中是沒有攔截方法,所有會直接呼叫自己的onTouchEvent()方法處理事件,如果事件被消費則事件消費結束,如果View沒有消費事件,則交給它的父ViewonTouchEvent()方法處理,如果父容器都不處理,最終會呼叫activity的onTouchEvent()方法。

9.事件分發要點:

android事件分發機制詳解

android事件分發機制詳解

android事件分發機制詳解

相關文章