Android Touch事件分发传递

362 阅读3分钟

touch事件一直是Android学习者一个头疼的问题,为了更好的学习事件的传递,我们来探索一下

touch事件有如下几种:

Activity中包括:

dispatchTouchEvent
onTouchEvent

ViewGroup有:

dispatchTouchEvent
onTouchEvent
onInterceptTouchEvent

View有:

dispatchTouchEvent
onTouchEvent

写一个demo,通过实践来总结事件传递的方式,页面布局如下,我们通过点击view来测试touch的传递过程

页面布局

首先,我们自定义三个view,Group1,Group2和view,分别重写Activity和他们的touch事件,通过点击View打印的日志来看view的传递

activity代码

activity Log截图

viewGroup1 代码

viewGroup1 log截图

viewGroup2 代码

viewGroup2 log截图

view 代码

view log截图

打log,看日志,总结规律

  • 默认情况下,这些方法都是super(即父类的默认实现的)。所以先看一下默认情况下,一个ACTION_DOWN和ACTION_UP事件是怎么传递的。给最里面的View一个触摸,产生touch事件。

log

默认情况下日志
事件传递过程,可以用如下图来展示
红色:ACTION_DOWN,紫色:ACTION_UP

  • 然后我们让dispatchTouchEvent()方法返回false(这里在viewGroup2里返回),log如下:
    事件传递过程,可以用如下图来展示
    红色:ACTION_DOWN,紫色:ACTION_UP

规律:

ACTION_DOWN事件会传递到上一级view的onTouch()事件里面处理。如果是在activity里的dispatchTouch()事件返回false, 因为activity已经没有上一级view了,所以事件会被直接消费掉(不会继续传递)。
ACTION_UP事件并没有按照类U型的结构去在View树传递,而是直接在Activity的onTouchEvent方法中消费掉了。

  • 然后我们让dispatchTouchEvent()方法返回true(这里在viewGroup2里返回),log如下:

事件传递过程,可以用如下图来展示

红色:ACTION_DOWN,紫色:ACTION_UP

规律:

ACTION_DOWN事件会在返回true的事件中直接消费掉,不会在继续传递。
ACTION_UP事件和down事件一样在返回true的事件中直接消费掉,不会传递。

  • 我们让onInterceptTouchEvent()方法返回false(这里在viewGroup2里返回),log如下

事件传递过程,可以用如下图来展示

红色:ACTION_DOWN,紫色:ACTION_UP
规律:

ACTION_DOWN事件传递和返回super传递一样,所以返回false和默认事件传递一样。
ACTION_UP事件和默认的传递一样。

  • 我们让onInterceptTouchEvent()方法返回true(这里在viewGroup2里返回),log如下

事件传递过程,可以用如下图来展示

红色:ACTION_DOWN,紫色:ACTION_UP
规律:

ACTION_DOWN:当在onInterceptTouchEvent()返回true时,事件会传递到自己的onTouchEvent()中处理
ACTION_UP:事件和默认的传递一样。

  • 我们让onTouchEvent()方法返回false(这里在view里返回),log如下

事件传递过程,可以用如下图来展示

红色:ACTION_DOWN,紫色:ACTION_UP
规律:

ACTION_DOWN事件传递和返回super传递一样,所以返回false和默认事件传递一样。
ACTION_UP事件和默认的传递一样。

  • 我们让onTouchEvent()方法返回true(这里在view里返回),log如下

事件传递过程,可以用如下图来展示
红色:ACTION_DOWN,紫色:ACTION_UP
规律:

ACTION_DOWN:事件在onTouch()被消费掉,不会在继续传递 ACTION_UP事件传递路径和ACTION_DOWN一样,在事件被消费掉之后不会继续传递

思考总结

ACTION_DOWN:
1.返回false和默认的传递路基一样。  
2.在dispatchTouchEvent()和onTouchEvent()中返回true会消费掉当前事件,不会在继续传递。  
3.在onInterceptTouchEvent()中返回true,事件会直接传递到自己的onTouchEvent()事件中,而不会向子view传递。  
ACTION_UP:
1.事件返回false是传递路径从当前activity的diapatchTouchEvent传递到自己的onTouchEvent()中。  
2.在dispatchTouchEvent()和onTouchEvent()中返回true会消费掉当前事件,不会在继续传递。传递路径和ACTION_DOWN路径一样。  
3.在onInterceptTouchEvent()中返回true,传递路径和1的路径一样。

当然,总结的规律还是要靠源码的逻辑支撑,下一期我会上源码分析,来支撑探究的规律