Android中的触屏事件分发机制

之前也自己学习过,但是当时学的不是很透彻而且有点忘了,重新总结一下。

首先,需要说一下,Android中的基本触屏事件主要有:按下、滑动、抬起。
分别对应的是MotionEvent类中的ACTION_DOWN,ACTION_MOVE,ACTION_UP。
而一个展示在我们面前的Activity大致有这么几层:
Activity -> PhoneWindow -> DecorView -> ViewGroup -> View
也就是说每个Activity都有一个Window对象,Window是一个抽象类,一般实现的是PhoneWindow,它会包含一个DecorView,这个就是整个窗口的根View,它其中的内容就是我们在布局文件中写的内容了。我们的布局文件都是在ViewGroup中包含一些控件,这就组成了一个Activity。
我们点击一下屏幕就产生一个事件,首先是最上层的Activity收到这个事件,它决定是否向下分发,我们一般操作的是从自定义ViewGroup开始的,因为在多控件重叠的时候如果处理不好点击事件的处理问题,就会导致一些控件无法响应。
事件的拦截与分发和处理主要由三个方法决定
顺序也是:分发-拦截-处理消费

  • dispatchTouchEvent
    事件分发,决定是否分发当前事件,如果不分发,也就表示事件到此之后不会往下走, 那就没有然后了。一般来讲不会改写这个方法,因为Activity、ViewGroup、View都有这个 方法,一旦不分发(返回true)结果只有一个,就是触屏事件没有消费者了,那么点击事件就等于没有了。
  • onInterceptTouchEvent(只有ViewGroup中才有这个方法)
    这个是一个很重要的方法,表示了是否拦截触屏事件。如果拦截,那么由于已经执行过事件分发,那这个事件就会传递到当前ViewGroup的onTouchEvent方法,由它进行事件处理,处理结束后返回上层的ViewGroup或Activity的onTouchEvent,其下层的View就没什么事了。如果不拦截,那么就会继续往下传递。
  • onTouchEvent
    一般在这个方法中处理触屏事件。处理完毕后默认向上返回。

下面通过一些例子来深刻认识一下,有一点要提的是,dispatchTouchEvent返回true表示消费了事件,就不进行分发;onInterceptTouchEvent返回true表示进行拦截,不继续传递;onTouchEvent返回true表示消费了事件,不用返回了。
首先是我的布局:



    
        
            
        
    

两个ViewGroup包了一个View。
大概这样:


Android中的触屏事件分发机制_第1张图片
Paste_Image.png

在默认的情况下,点击一下绿色区域(由于按下与抬起是两个事件,测试中只分析按下事件):


Android中的触屏事件分发机制_第2张图片
Paste_Image.png

这么来看的话,默认情况下,来一个事件,首先是dispatchTouchEvent进行分发,然后onInterceptTouchEvent判断是否拦截,不拦截就继续往下,也就是上层不断的往下层分发,一路不拦截,直到不能继续向下,然后最底层的View的onTouchEvent处理事件,再一路向上执行onTouchEvent。
如果ViewGroup1拦截了事件(onInterceptTouchEvent返回true):


Paste_Image.png

果然,分发了之后,进行拦截的话表示就不向下层继续传递了,那么就是当前ViewGroup1的onTouchEvent处理,处理结束后向上返回。

那如果在onTouchEvent中消费了事件呢?
将View中的onTouchEvent返回true:


Android中的触屏事件分发机制_第3张图片
Paste_Image.png

果然,onTouchEvent返回true,表示这个事件我消费完了,没了。
那么就不用再向上层传递了。同理,如果ViewGroup2的onTouchEvent返回true,那就表示ViewGroup2把事件消费了,事件没了,不用往上传了。

Android中的触屏事件分发机制_第4张图片
Paste_Image.png

上面的测试都是点击的绿色区域,当然了,如果点击的是蓝色区域,那么就是ViewGroup2在最底层,处理方式还是相同的。

后面自己自定义控件或布局重叠的时候遇到问题再回来补充。

你可能感兴趣的:(Android中的触屏事件分发机制)