Android 事件分发

郭神的博客

当我们手指触摸屏幕的时候,事件其实是通过
Activity -> ViewGroup -> View的流程到达我们触摸事件的View的。

事件分发三个重要方法:

  1. 分发、DispatchTouchEvent()
  2. 拦截、onInterceptTouchEvent()
  3. 消费、onTouchEvent()

接下来就按照Activity -> ViewGroup -> View 的流程来大致说一下事件分发机制。

Activity:
Android 事件分发_第1张图片

当我们手指触摸屏幕时,会触发一个Action_Down的事件,当前Activity首先会做出响应,这时会走到 Activity的dispatchTouchEvent() 方法内。在这个方法内部的简单逻辑如下:

调用getWindow.superDispatchTouchEvent(),如果该方法返回true,表示当前事件已经被处理掉。否则就需要调用Activity的onTouchEvent()方法自己处理

为什么会走到ViewGroup的dispatchTouchEvent()?
getWindow()方法返回了一个Window对象,PhoneWindow是Window的唯一实现类,所以相当于调用了PhoneWindow的superDispatchTouchEvent().

在PhoneWindow的方法中调用的是的mDecor.superDispatchTouchEvent(event)。这个mDecor就是DecorView,DecorView是FrameLayout的子类,FrameLayout是ViewGroup的子类,所以本质上调用的是ViewGroup的DispatchTouchEvent().

ViewGroup:的dispatchTouchEvent()
Android 事件分发_第2张图片
通过onInterceptTouchEvent()方法判断是否拦截,如果拦截则return自己的onTouchEvent()。

子View:的dispatchTouchEvent()
Android 事件分发_第3张图片
如果不拦截,调用child.dispatchTouchEvent(),这里会调用子view的onTouchEvent方法,如果子view的onTouchEvent方法返回true,则表示事件被处理。
如果未处理,事件会继续向上传递,调用父View的onTouchEvent方法,直到有view处理该事件,如果一直未处理,最终到达Activity的onTouchEvent方法终止。

onTouch 和 onTouchEvent 的区别

**这两个方法都在 View 的 dispatchTouchEvent()**中

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

满足以上三点,则返回true。

所以onTouch()方法是优先于onTouchEvent()方法执行的,如果onTouch()方法返回true,那么后续操作会被拦截,onTouchEvent方法不会被执行,onClick方法在onTouchEvent中,所以也不会被执行

Android 事件分发_第4张图片

你可能感兴趣的:(Android)