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

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