12.2019安卓事件傳遞機制探索

現在佈局中有這樣一層結構,當我觸摸屏幕的時候,我要看事件傳遞的順序,分別重寫了
Activity的dispatchTouchEvent方法,onTouchEvent方法;
MyViewGroup的dispatchTouchEvent方法,onInterceptTouchEvent方法,onTouchEvent方法;
MyTextView的dispatchTouchEvent方法,onTouchEvent方法;
並且分別在每個方法中打印log

    <com.rzm.myapplication.MyViewGroup
        android:layout_width="match_parent"
        android:background="#f00"
        android:layout_height="match_parent">
        <com.rzm.myapplication.MyTextView
            android:layout_marginLeft="20dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:layout_width="match_parent"
            android:background="#f0f"
            android:layout_height="400dp" />
    </com.rzm.myapplication.MyViewGroup>

1.默認所有方法都返回super.xxx()

05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MainActivity dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MyViewGroup dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MyViewGroup onInterceptTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MyTextView dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MyTextView onTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MyViewGroup onTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.594 2517-2517/com.rzm.myapplication I/MainActivity onTouchEvent: 按下ACTION_DOWN
05-18 22:10:20.684 2517-2517/com.rzm.myapplication W/MainActivity dispatchTouchEvent: 鬆開ACTION_UP
05-18 22:10:20.684 2517-2517/com.rzm.myapplication W/MainActivity onTouchEvent: 鬆開ACTION_UP

可以看到,ACTION_DOWN事件從Activity dispatchTouchEvent 傳遞到ViewGroup dispatchTouchEvent,又傳遞到View dispatchTouchEvent,然後傳遞到View的onTouchEvent ,由於在最底層View的onTouchEvent中事件也沒有被處理,此時又開始往上回傳,傳遞到ViewGroup的onTouchEvent ,ViewGroup也沒有處理,然後又傳遞到Activity的onTouchEvent ,由於ACTION_DOWN事件都沒有進行處理,那麼按下事件就丟失了,最後執行了Activity的dispatchTouchEvent和onTouchEvent的ACTION_UP事件

2.在1的基礎上做修改,設置Activity的dispatchTouchEvent返回true,或者false

true表示Activity的dispatchTouchEvent方法要消費這個事件,所以就不會往下傳遞
false表示Activity的dispatchTouchEvent方法不再分發這個事件,所以也不會往下傳遞,打印如下

05-18 22:24:23.734 2675-2675/com.rzm.myapplication I/MainActivity dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:24:23.794 2675-2675/com.rzm.myapplication W/MainActivity dispatchTouchEvent: 鬆開ACTION_UP

3.在1的基礎上做修改,設置ViewGroup的dispatchTouchEvent返回true

true表示有人要消費這個事件了,那麼誰消費,就走到誰那算終點,並且因爲被消費了,所以是一個完整的事件過程,Down move up事件都有(這裏沒有move,因爲只是點了一下)

05-18 22:38:54.093 3375-3375/com.rzm.myapplication I/MainActivity dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:38:54.093 3375-3375/com.rzm.myapplication I/MyViewGroup dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:38:54.153 3375-3375/com.rzm.myapplication W/MainActivity dispatchTouchEvent: 鬆開ACTION_UP
05-18 22:38:54.153 3375-3375/com.rzm.myapplication W/MyViewGroup dispatchTouchEvent: 鬆開ACTION_UP

4.在1的基礎上做修改,設置ViewGroup的dispatchTouchEvent返回false

返回false表示不再向下傳遞,那麼此時ViewGroup的onInterceptTouchEvent和onTouchEvent都不會執行,而是將ACTION_DOWN事件向上傳遞到了Activity的onTouchEvent方法中,然後按下事件流程就走完了,開始走ACTION_UP的事件,那麼就執行了Activity的dispatchTouchEvent,因爲在ACTION_DOWN事件時,ViewGroup已經表明了不再向下傳遞,那麼走完Activity的dispatchTouchEvent,就走到了Activity的onTouchEvent方法的ACTION_UP

05-18 22:43:19.150 3478-3478/com.rzm.myapplication I/MainActivity dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:43:19.150 3478-3478/com.rzm.myapplication I/MyViewGroup dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:43:19.150 3478-3478/com.rzm.myapplication I/MainActivity onTouchEvent: 按下ACTION_DOWN
05-18 22:43:19.220 3478-3478/com.rzm.myapplication W/MainActivity dispatchTouchEvent: 鬆開ACTION_UP
05-18 22:43:19.220 3478-3478/com.rzm.myapplication W/MainActivity onTouchEvent: 鬆開ACTION_UP

5.在1的基礎上做修改,設置ViewGroup的onInterceptTouchEvent返回true

ViewGroup雖然攔截了事件,但是在onTouchEvent方法中卻沒有進行處理,所以ACTION_DOWN事件還是會回傳到MainActivity onTouchEvent方法中,仍然沒有處理,那麼按下事件完成,執行擡起事件

05-18 22:54:49.241 3641-3641/com.rzm.myapplication I/MainActivity dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:54:49.241 3641-3641/com.rzm.myapplication I/MyViewGroup dispatchTouchEvent: 按下ACTION_DOWN
05-18 22:54:49.241 3641-3641/com.rzm.myapplication I/MyViewGroup onInterceptTouchEvent: 按下ACTION_DOWN
05-18 22:54:49.241 3641-3641/com.rzm.myapplication I/MyViewGroup onTouchEvent: 按下ACTION_DOWN
05-18 22:54:49.241 3641-3641/com.rzm.myapplication I/MainActivity onTouchEvent: 按下ACTION_DOWN
05-18 22:54:49.331 3641-3641/com.rzm.myapplication W/MainActivity dispatchTouchEvent: 鬆開ACTION_UP
05-18 22:54:49.331 3641-3641/com.rzm.myapplication W/MainActivity onTouchEvent: 鬆開ACTION_UP

6.在1的基礎上做修改,設置ViewGroup的onInterceptTouchEvent返回true,ViewGroup要攔截事件,那麼通常它就應該來處理這個事件,將onTouchEvent方法設置爲返回true

所以ViewGroup攔截了事件後並且在onTouchEvent中進行了處理,那麼ViewGroup的onTouchEvent會執行一個完整的事件

05-18 23:00:56.096 3801-3801/com.rzm.myapplication I/MainActivity dispatchTouchEvent: 按下ACTION_DOWN
05-18 23:00:56.096 3801-3801/com.rzm.myapplication I/MyViewGroup dispatchTouchEvent: 按下ACTION_DOWN
05-18 23:00:56.096 3801-3801/com.rzm.myapplication I/MyViewGroup onInterceptTouchEvent: 按下ACTION_DOWN
05-18 23:00:56.096 3801-3801/com.rzm.myapplication I/MyViewGroup onTouchEvent: 按下ACTION_DOWN
05-18 23:00:56.176 3801-3801/com.rzm.myapplication W/MainActivity dispatchTouchEvent: 鬆開ACTION_UP
05-18 23:00:56.176 3801-3801/com.rzm.myapplication W/MyViewGroup dispatchTouchEvent: 鬆開ACTION_UP
05-18 23:00:56.176 3801-3801/com.rzm.myapplication W/MyViewGroup onTouchEvent: 鬆開ACTION_UP

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