道长说了这么多自定义View,还没说自定义View会遇到什么问题,其实这个问题不止在自定义View中存在。在开发中遇到控件嵌套,堆叠都会出现,比如:点击子控件,子控件接收不到点击事件等等。这里道长简单说一下Android的事件拦截机制。重点是记录一下道长的想法。这里有大牛写的更详细更深入,想看的话可以点击传送门:android事件拦截处理机制详解。
View布局
-
控件方法
手机当前界面为Activity,在当前界面中有ViewGrouopA控件及其子控件ViewGroupB,ViewGroupB的子控件View。
在ViewGroupA/ViewGroupB中都有方法dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent()方法,在Activity/view中只有dispatchTouchEvent()与onTouchEvent()方法。dispatchTouchEvent(MotionEvent ev) - 用于Touch事件的分发
onInterceptTouchEvent(MotionEvent ev) - 用于拦截Touch事件
onTouchEvent(MotionEvent event) - 用于处理Touch事件 事件传递
1.当手机界面有触摸事件MotionEvent发生down动作时
分发判断:会先把事件传递给Activity,先调用dispatchTouchEvent()方法将事件传递给子控件ViewGroupA。
2.ViewGroupA接收到事件
分发判断:先调用dispatchTouchEvent()方法,再调用onInterceptTouchEvent()方法判断是否拦截事件。如果onInterceptTouchEvent()方法返回的是true;就调用onTouchEvent()方法消费掉该事件。如果onInterceptTouchEvent()方法返回的是false,就将事件传递给子控件ViewGroup。
3.ViewGroupB接收到事件
分发判断:先调用dispatchTouchEvent()方法,再调用oninterceptTouchEvent()方法判断是否拦截事件。如果onInterceptTouchEvent()方法返回的是true;就调用onTouchEvent()方法消费掉该事件。如果onInterceptTouchEvent()方法返回的是false,就将事件传递给子控件View。
4.View接收到事件
分发判断:先调用dispatchTouchEvent()方法,然后直接调用onTouchEvent()方法处理事件。如果onTouchEvent()方法返回的是true,表示消费了事件;如果返回的是false,表示不需要这个事件,对这个事件不进行任何处理。将这个事件返回到调用处View控件的dispatchTouchEvent()方法,再由dispatchTouchEvent()方法把事件返回到父控件ViewGroupB。
5.ViewGroupB直接调用onTouchEvent()方法处理事件
返回判断:如果onTouchEvent()方法返回的是true,表示消费了事件;如果返回的是false,表示不需要这个事件,对这个事件不进行任何处理。将这个事件由dispatchTouchEvent()方法把事件返回到父控件ViewGroupA。
6.ViewGroupA直接调用onTouchEvent()方法处理事件
返回判断:如果onTouchEvent()方法返回的是true,表示消费了事件;如果返回的是false,表示不需要这个事件,对这个事件不进行任何处理。将这个事件由dispatchTouchEvent()方法把事件返回到Activity。
7.Activity直接调用onTouchEvent()方法处理事件
返回判断:如果onTouchEvent()方法返回的是true,表示消费了事件;如果返回的是false,表示不需要这个事件,对这个事件不进行任何处理,事件丢失。示意图
关于Android事件拦截机制道长就先记录到这里,以后有了新的想法在记录。希望这篇博客能够为你提供一些帮助。