Android事件分发机制

本文出自:【openXu的博客】

   在平时的工作中,事件分发机制是非常重要的,之前虽然说比较了解,出现问题也能得到解决,但是一直没有系统的总结一下,有些地方也不能一句话说死,今天得空简单的总结记录如下:

相关类及方法

     这里写图片描述

重要方法的作用

  dispatchTouchEvent():此方法是View中定义的,ViewGroup重写了它。View中dispatchTouchEvent()将事件交给OnTouchListener处理,并调用onTouchEvent(),这些都是让控件自己处理事件;而ViewGroup中dispatchTouchEvent()是将事件分发给他的子控件处理,如果子控件没有消费掉事件,然后再自己处理,自己处理的方式跟View中一样(最后调用的是super.dispatchTouchEvent() )

  onInterceptTouchEvent(ev): ViewGroup的方法,是否拦截事件,如果返回true,则子控件无法获得事件 
  setOnTouchListener(): View中的方法,设置Touch监听,回调onTouch()方法 
  onTouchEvent(): View中的方法,解析处理事件 
  setOnClickListener(): View中的方法,设置点击事件,回调onClick()方法

方法调用图

     这里写图片描述

分析

  Android事件的传递是从外层控件传递到内层控件(父控件传子控件)的,屏幕收到事件后首先传递给最外层的容器,调用它的dispatchTouchEvent()方法,dispatchTouchEvent()是View中的方法,ViewGroup重写了它。

  ViewGroup的dispatchTouchEvent()首先判断事件拦截是否被禁用掉了(通过disallowIntercept,此值默认是false,可以通过requestDisallowInterceptTouchEvent()设置),如果没被禁用,则会调用onInterceptTouchEvent()判断事件是否被拦截。如果外层控件的onInterceptTouchEvent()返回true,事件则不会继续往下传递,如果返回false(和不禁用一样)则事件不会被拦截,会遍历它的子控件,判断触摸点是否在子控件范围内。

  ①、如果在,就会调用子控件的dispatchTouchEvent(),子控件如果是容器又会重复上面步骤,如果不是容器,就会执行View的dispatchTouchEvent(),下面插播View的dispatchTouchEvent()分析:

  View对dispatchTouchEvent()的实现判断控件是否可用(enable)&& 是否设置了OnTouchListener,如果为true会调用监听的onTouch(),onTouch()如果返回false,说明事件没有被消费掉,会继续调用onTouchEvent()方法。

public boolean dispatchTouchEvent(MotionEvent event) {
    if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
            mOnTouchListener.onTouch(this, event)) {
        return true;
    }
    return onTouchEvent(event);
}

  onTouchEvent():该方法会解析一系列的ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件(按下、滑动、抬起等),在ACTION_UP时会调用performClick()方法,该方法判断有没有setOnClickListener,如果设置了就会回调onClick()方法。这个方法也有返回值,如果在某个action返回了false,则后面就不会再执行该方法了(收不到事件了)。

扫描二维码关注公众号,回复: 1105241 查看本文章

  如果子控件可点击或者需要接受事件,onTouchEvent()一定会返回true,这样在ViewGroup的dispatchTouchEvent()中收到子控件的返回值后也继续返回true,事件到此终止。

  ②、如果不在任何子控件范围内(点击空白处),或者子控件没有处理掉事件(dispatchTouchEvent()返回false),则ViewGroupdispatchTouchEvent()会继续往下执行调用super.dispatchTouchEvent()(View中的dispatchTouchEvent()),这也就是ViewGroup自己处理事件

    这里写图片描述

猜你喜欢

转载自blog.csdn.net/wangxueqing52/article/details/80430962