Android Touch事件分发深入了解

2019-12-10 18:29:26丽君

    根据以上代码可以知道,touch事件会交由Window的superDispatchTouchEvent进行分发,若这个方法返回true,意味touch事件的分发过程结束,返回false则说明经过层层分发,没有子View对这个事件进行处理,即所有子View的onTouchEvent方法都返回false(即这个touch事件没有被“消耗”)。这时会调用Activity的onTouchEvent方法来处理这个touch事件。

    在Window的superDispatchTouchEvent方法中,首先会把touch事件分发给DecorView,因为它是当前用户界面的顶级View。Window的superDispatchTouchEvent方法如下:

public abstract boolean superDispatchTouchEvent(MotionEvent ev);
    是个抽象方法,这个方法由Window的实现类PhoneWindow实现,PhoneWindow的superDispatchTouchEvent方法的代码如下:

public boolean superDispatchTouchEvent(MotionEvent ev) {
  return mDecor.superDispatchTouchEvent(event);
}

    由以上代码可得,PhoneWindow的superDispatchTouchEvent方法实际上是通过DecorView的superDispatchTouchEvent方法来完成自己的工作,也就是说,当前Activity的Window直接将这个touch事件传递给了DecorView。也就是说,目前touch事件已经经过了如下的分发:Activity-->Window-->DecorView。

b. 顶级View对touch事件的分发

    经过Activity与Window的分发,现在touch事件已经被传递到了DecorView的dispatchTouchEvent方法中。DecorView本质上是一个ViewGroup(更具体的说是FrameLayout),ViewGroup的dispatchTouchEvent方法所做的工作可以分为如下几个阶段,第一个阶段的主要代码如下:

//Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
  //Throw away all previous state when starting a new touch gesture.
  //The framework may have dropped the up or cancel event for the previous gesture due to an app switch, ANR, or some other state change.
  cancelAndClearTouchTargets(ev);
  resetTouchState();
}