Android 事件處理全面剖析

篇外話:先來說下今天的日期,今天是2015年02月18日也就是大年三十,大家都在歡歡喜喜的準備過大年,活動也各式各樣,搓麻將、打撲克、放煙花、準備看春晚,而我卻還在敲代碼,我只想說身爲程序員的我們,真的屌絲的不能再屌絲了。雖然很屌絲,但我在這裏還是要給大家拜個年,祝大家羊年喜氣洋洋、寫出來的代碼少 bug、產品少改需求!當然當大家看到這篇 blog 的時候已經過完了年,因爲我寫這篇 blog 是在家裏,而我家裏木有網絡,所以還得等到到了工作之地才能放出來,好了,迴歸正題。

Android 事件處理機制說難也不難,說簡單也不簡單,爲什麼這麼說呢?因爲我相信大部分有了一定 Android 基礎的同學,想要分析 Android 事件處理機制,都是可以分析出來了;但要靈活運用它卻又覺得很吃力,而且往往需要查閱各種資料文檔,才能真正把它運用起來。今天我帶領大家對 Android 事件處理機制做一次全方位的分析,從而達到大家對 Android 事件處理有一個更深、更形象的認識!

一、初體驗:
相信大部分的人對 Android 事件處理機制的分析,都是通過打印 log 的方式,這裏也是通過這種方式來分析;首先準備三個類 MainActivity 、EventLayout 、EventTextView ,這幾個類分別是什麼都做了些什麼呢?我們看看代碼就知道。
1、MainActivity

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean handle = false ;
        String str  = "ACTION_DOWN";
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                handle = true ;
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy","=====Activity=====dispatchTouchEvent========"+str) ;
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        String str  = "ACTION_DOWN";
        boolean handle = false ;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                handle = true ;
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy","=====Activity=====onTouchEvent========"+str) ;
        return super.onTouchEvent(event);
    }
}

2、EventLayout

/**
 * Created by gyzhong on 15/2/18.
 */
public class EventLayout extends LinearLayout {
    public EventLayout(Context context) {
        super(context);
    }

    public EventLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EventLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        String str  = "ACTION_DOWN";
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy", "=====ViewGroup=====onInterceptTouchEvent========"+str) ;
        if(handle){
            return handle ;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean handle = false ;
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy", "=====ViewGroup=====dispatchTouchEvent========"+str) ;
        if(handle){
            return handle ;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        String str  = "ACTION_DOWN";
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy","=====ViewGroup=====onTouchEvent========"+str) ;
        return super.onTouchEvent(event);
    }
}

3、EventTextView

/**
 * Created by gyzhong on 15/2/18.
 */
public class EventTextView extends TextView {
    public EventTextView(Context context) {
        super(context);
    }

    public EventTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EventTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        String str  = "ACTION_DOWN";
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy", "=====View=====dispatchTouchEvent========"+str+ ",getX() ="+ev.getX()) ;
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        String str  = "ACTION_DOWN";
        boolean handle = false ;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy","=====View=====onTouchEvent========"+str) ;
        return super.onTouchEvent(event);
    }
}

通過代碼可以看到,3個類基本上什麼都沒做,只是重寫了父類的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent方法,也只是在其中加入了調試信息,那再來看看 xml

<com.gyzhong.eventdemo.EventLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center_horizontal"
>
    <com.gyzhong.eventdemo.EventTextView
        android:layout_width="120dp"
        android:layout_height="60dp"
        android:gravity="center"
        android:text="eventText"/>
</com.gyzhong.eventdemo.EventLayout>

這裏把我們重寫的 自定義的 View 放入佈局中。運行代碼,開始調試,然後點擊EventTextView可以看到 log 信息:

=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP

通過信息和結合我們所學的知識點,還是很容易得出結論來:
Activity 的 dispatchTouchEvent的事件分發給ViewGroup,ViewGroup先通過事件攔截onInterceptTouchEvent(只有 ViewGroup 纔有此方法)來判斷,是否攔截,如果沒有攔截則將事件分發給 View 的分發機制dispatchTouchEvent;View 獲取到事件後,就開始調用 onTouchEvent 方法,如果 View 的 onTouchEvent 未把事件消費掉,則把事件有傳遞給 ViewGroup 的 onTouchEvent,同理,ViewGroup 未把事件消費掉,繼續往下級傳到了 Activity 的 onTouchEvent 事件處理中。文字講解終究是有點難理解,需要結合圖文來講解,那麼我們來看下下面這張圖,應該很清晰明瞭。
這裏寫圖片描述

通過上圖,我們可以得出以下幾點結論:
1、Android 事件傳遞是層級傳遞的;
2、dispatchTouchEvent從底層向上層傳遞,而onTouchEvent剛好相反;
3、onInterceptTouchEvent返回爲 true 時,將執行同層級的onTouchEvent,而dispatchTouchEvent和onTouchEvent返回 true 時,將終止事件的傳遞。
上面我們提到了兩個關鍵詞,攔截和消費,其實都是圖片中表示的 return 返回值,在 dispatchTouchEvent 我們習慣用攔截,而在 onTouchEvent 中則習慣用消費來說明(個人習慣而已)。return false 表示事件未被dispatchTouchEvent攔截,也未被onTouchEvent消費。好了,到此我們的Android 事件處理機制分析完了,感謝大家的閱讀。汗、汗、汗、、、 真的分析完了嗎,如果只是這樣就結束了,我也不會在大過年的,在這裏苦逼苦逼的寫 blog。那麼接下來我們進入第二階段。

二、深度剖析
還記得前面第一階段的標題”初體驗”爲什麼叫初體驗呢?大致可以認爲是我們的第一印象,我們最初感覺出來的東西。無論是根據自己的邏輯來推理,還是根據剛剛我們看到的調試信息來看,事件處理機的制整體流程都是按照上面圖1-1的流程來走的。但是,細心的同學肯定看到了最後兩行調試信息

=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP

對,你沒有看錯,我也沒有調錯,ACTION_UP的時候它確實只打印了兩行,並都是在 Activity 中打印的。並不像 ACTION_DOWN 的時候執行了

=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN

也許這樣看還不明顯,再來看看一下調試信息

=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP

這裏可以看到只有在 ACTION_DOWN 的時候是按照我們分析的流程圖來執行,而 ACTION_MOVE、ACTION_UP 都只是執行了 Activity 的dispatchTouchEvent和onTouchEvent,這是爲什麼?難道我們不是按照上面那張流程圖的流程來執行?這裏我可以肯定的告訴大家,上面那張圖的流程是絕對沒有問題的,只是有些事件被攔截或消費掉。並且這裏告訴大家一個結論:
ViewGroup 和 View的dispatchTouchEvent分發事件在 action 爲ACTION_DOWN時沒有被攔截且onTouchEvent的處理事件在 action 爲ACTION_DOWN時未被消費,當 action 爲ACTION_MOVE或ACTION_UP時,dispatchTouchEvent和onTouchEvent只有在 activity 被調用。想搞清楚和驗證這個結論的同學,可以自己根據源碼深入探究!
通過以上結論,可知,在手指滑動或者擡起的時候,ViewGroup 和 View 的dispatchTouchEvent和onTouchEvent未被執行,因爲事件未被攔截或者消費。
我在網上看過一些 Android 事件處理機制的帖子和 bolg,我記得有這樣一個問題,爲什麼我在分析 Android 事件處理的時候,用 TextView 和 Button ,分析出來的結果不一樣呢?這裏我們用的是 TextView 分析的,我們也來看看 Button 的效果,到底哪裏不一樣。新建一個 EventButton類和 EventTextView 一樣,除了繼承的對象不同之外。

EventButton
/**
 * Created by gyzhong on 15/2/18.
 */
public class EventButton extends Button {
    public EventButton(Context context) {
        super(context);
    }

    public EventButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EventButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        String str  = "ACTION_DOWN";
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy", "=====View=====dispatchTouchEvent========"+str+ ",getX() ="+ev.getX()) ;
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        String str  = "ACTION_DOWN";
        boolean handle = false ;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                str = "ACTION_DOWN";
                break ;
            case MotionEvent.ACTION_MOVE:
                str = "ACTION_MOVE";
                break;
            case MotionEvent.ACTION_UP:
                str = "ACTION_UP";
                break;
        }
        Log.v("zgy","=====View=====onTouchEvent========"+str) ;
        return super.onTouchEvent(event);
    }
}

記得別忘記修改 xml 中的內容

<com.gyzhong.eventdemo.EventLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center_horizontal"
>
    <com.gyzhong.eventdemo.EventButton
        android:layout_width="120dp"
        android:layout_height="60dp"
        android:gravity="center"
        android:text="eventButton"/>
</com.gyzhong.eventdemo.EventLayout>

再次運行代碼,果然,結果不一樣

=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onInterceptTouchEvent========ACTION_MOVE
=====View=====dispatchTouchEvent========ACTION_MOVE
=====View=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onInterceptTouchEvent========ACTION_MOVE
=====View=====dispatchTouchEvent========ACTION_MOVE
=====View=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====onInterceptTouchEvent========ACTION_UP
=====View=====dispatchTouchEvent========ACTION_UP
=====View=====onTouchEvent========ACTION_UP

我們根據調試結果再加上流程圖不難推測出,在 View 的 onTouchEvent 的事件處理機制中把事件消費掉了,並且在 action 爲 ACTION_DOWN、ACTION_MOVE、ACTION_UP 的時候全部消費掉了,所以不會再往下執行,那我們就來看看源碼是否如此。
進入到 View 的onTouchEvent方法中

public boolean onTouchEvent(MotionEvent event) {
      //省略部分代碼
      if (((viewFlags & CLICKABLE) == CLICKABLE ||
                (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
                     }
    //省略很多代碼
            return true;
       }

        return false;
}

以上代碼,我把有用的幾行提取出來了,可以看到,有一個判斷條件,如果 View 是可以點擊的狀態,return true 事件將會被消費掉,否則 return false 不會被消費掉。而我們都知道 TextView 默認狀態是不可點擊的, Button 是可以點擊的,所以這也就是爲什麼 TextView 和 Button 的調試效果不一樣,如果把 Button 設爲不可點擊,效果就和 TextView 的完全一樣,有興趣的同學可以自己嘗試一下。

四、總結
講了那麼多,其實核心就是那張圖片,只要掌握了那張圖片中事件的流程基本上就沒什麼問題了;
這張圖反應出來的信息有:

1、Android 事件傳遞是層級傳遞的;
2、dispatchTouchEvent從低級向上級傳遞,而onTouchEvent剛好相反;
3、onInterceptTouchEvent返回爲 true 時,將執行同級的onTouchEvent,而dispatchTouchEvent和onTouchEvent返回 true 時,將終止事件的傳遞。

還有一點特別重要,也是比較難理解的一點,就是我前面說的那個結論。

ViewGroup 和 View的dispatchTouchEvent分發事件在 action 爲ACTION_DOWN時沒有被攔截且onTouchEvent的處理事件在 action 爲ACTION_DOWN時未被消費,當 action 爲ACTION_MOVE或ACTION_UP時,dispatchTouchEvent和onTouchEvent只有在 activity 被調用。

最後我將在下篇 blog 中,通過自定義通用型的下拉刷新來實戰事件處理機制,如果有興趣的同學,可以關注。

這裏附上一張 時序圖和log 信息
這裏寫圖片描述

Activity dispatchTouchEvent——->Action == ACTION_DOWN return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


Activity dispatchTouchEvent——->Action == ACTION_MOVE return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


Activity dispatchTouchEvent——->Action == ACTION_UP return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP


ViewGroup dispatchTouchEvent——->Action == ACTION_DOWN return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====onTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


ViewGroup dispatchTouchEvent——->Action == ACTION_MOVE return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


ViewGroup dispatchTouchEvent——->Action == ACTION_UP return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


ViewGroup onInterceptTouchEvent——->Action == ACTION_DOWN return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


View dispatchTouchEvent——->Action == ACTION_DOWN return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onInterceptTouchEvent========ACTION_MOVE
=====View=====dispatchTouchEvent========ACTION_MOVE
=====View=====onTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====onInterceptTouchEvent========ACTION_UP
=====View=====dispatchTouchEvent========ACTION_UP
=====View=====onTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


View dispatchTouchEvent——->Action == ACTION_MOVE return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP




View dispatchTouchEvent——->Action == ACTION_UP return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


View onTouchEvent ——->Action == ACTION_DOWN return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onInterceptTouchEvent========ACTION_MOVE
=====View=====dispatchTouchEvent========ACTION_MOVE
=====View=====onTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====onInterceptTouchEvent========ACTION_UP
=====View=====dispatchTouchEvent========ACTION_UP
=====View=====onTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


View onTouchEvent ——->Action == ACTION_MOVE return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


View onTouchEvent ——->Action == ACTION_UP return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


ViewGroup onTouchEvent ——->Action == ACTION_DOWN return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====dispatchTouchEvent========ACTION_MOVE
=====ViewGroup=====onTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====dispatchTouchEvent========ACTION_UP
=====ViewGroup=====onTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP


ViewGroup onTouchEvent ——->Action == ACTION_MOVE return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP

ViewGroup onTouchEvent ——->Action == ACTION_UP return true
=====Activity=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====dispatchTouchEvent========ACTION_DOWN
=====ViewGroup=====onInterceptTouchEvent========ACTION_DOWN
=====View=====dispatchTouchEvent========ACTION_DOWN
=====View=====onTouchEvent========ACTION_DOWN
=====ViewGroup=====onTouchEvent========ACTION_DOWN
=====Activity=====onTouchEvent========ACTION_DOWN
=====Activity=====dispatchTouchEvent========ACTION_MOVE
=====Activity=====onTouchEvent========ACTION_MOVE
=====Activity=====dispatchTouchEvent========ACTION_UP
=====Activity=====onTouchEvent========ACTION_UP

源碼下載地址:Android 事件處理機制

發佈了46 篇原創文章 · 獲贊 9 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章