Android事件分发机制

        在Android开发过程中尝尝会遇到滑动冲突等问题,这时候就需要用到事件分发的机制来解决了。

1、了解触摸事件

        首先需要了解下Android中的触摸事件。我们对屏幕的点击,滑动,抬起等一系的动作都是由一个一个MotionEvent对象组成的。根据不同动作,主要有以下三种事件类型:

1.ACTION_DOWN:手指刚接触屏幕,按下去的那一瞬间产生的事件
2.ACTION_MOVE:手指在屏幕上移动时候产生的事件
3.ACTION_UP:手指从屏幕上松开的瞬间产生的事件

        触摸点击操作是ACTION_DOWN->ACTION_UP;滑动事件操作是ACTION_DOWN->ACTION_MOVE->ACTION_UP。

        事件分发的本质就是点击事件传递的过程。

2、解析分发事件

 2.1  事件分发的对象 

        Android的点击事件会在Activity、ViewGroup、View及其派生类中传递。

                                       Android事件分发机制

      Android事件分发机制  

事件传递的过程为:Activity -> ViewGroup -> View

2.2 事件分发的方法

        事件在分发过程中会通过dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()这3个方法来协作完成。

           Android事件分发机制

接下来细说一下这3个方法所对应返回值的处理结果

dispatchTouchEvent()

当监听到有触摸事件时,首先由Activity进行捕获,然后事件就进入事件分发的流程。Activity本身没有事件拦截,从而将事件传递给最外层的View的dispatchTouchEvent(MotionEvent ev)方法,该方法将对事件进行分发。

  • return true : 事件被消费。
  • return false :停止分发,交由上层控件的onTouchEvent方法进行消费,如果本层控件是Activity,那么事件将被系统消费、处理。
  • super.dispatchTouchEvent(ev): 将事件交由本层的事件拦截onInterceptTouchEvent方法处理。
onInterceptTouchEvent()
该方法在上述表格中讲了,只会在ViewGroup中存在,它对事件进行拦截处理。
  • return true: 对事件拦截,交由本层的onTouchEvent进行处理。
  • return false: 不拦截,分发到子View,由子View的dispatchTouchEvent方法处理。
  • super.onInterceptTouchEvent(ev):默认表示事件拦截,交由本层的onTouchEvent进行处理。
onTouchEvent()

该方法对事件进行消费处理。

  • return true: 该View消费此次事件。
  • return false: 不响应事件,不断的传递给上层的onTouchEvent方法处理,直到某个View的onTouchEvent返回true,则认为该事件被消费。如果到最顶层View还是返回false,那么该事件不消费,将交由Activity的onTouchEvent进行处理。
  • return super.onTouchEvent: 结果与return返回false一样。

由上述可以得出如下流程图:

Android事件分发机制


总结

        上述对Android事件分发机制浅显的讲解了一下,事件传递过程为Activity -> ViewGroup -> View,每个对象中又有dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent(),其中onInterceptTouchEvent()方法只存在于ViewGroup ,根据上述的流程图,我们就可以解决Android中的事件冲突问题,冲突问题为什么会产生就是因为事件在分发的过程中,可能我们需要处理的是View层的事件,但是实际上却在ViewGroup 进行了消费,所以我可以根据事件分发的流程和方法很好的来处理事件冲突的问题。这一期讲的比较粗浅,只是根据术的层面来讲解了,有机会出一期源码分析的博客给大家。