Android事件分发之Activity篇 -- dispatchTouchEvent、onTouchEvent之间关系

Android事件分发之Activity篇 – dispatchTouchEvent、onTouchEvent之间关系

由前面两篇文章的分析可知,在设备获取到事件之后首先流转到的既是Activity,如果在所有View都不处理Touch事件的情况下最后也是传回Activity处理。首先从Activity的dispatchTouchEvent方法来分析。

首先从Activity的dispatchTouchEvent方法源码看起:

public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

源码看起来很简短,分析源码可以可发现:
1.onUserInteraction() 在Activity中为空方法。留给用户来重写的。

2.Activity中对事件的分发是通过getWindow().superDispatchTouchEvent(ev)来实现的,getWindow()是获取windows的具体唯一实现PhoneWindow,所以可以去PhoneWindow查找superDispatchTouchEvent()方法。

PhoneWindow中superDispatchTouchEvent源码:

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

看过源码的应该知道mDecor即为DecorView,DecorView为一个FrameLayout(既调用setContentView方法时的父view),我们知道FrameLayout父类也为ViewGroup,所以到此事件分发就由Activity传到了ViewGroup中去了,最后调用ViewGroup的dispatchTouchEvent进行分发了。Activity传递到ViewGroup的流程如下:
Android事件分发之Activity篇 -- dispatchTouchEvent、onTouchEvent之间关系_第1张图片

3.Activity事件分发方法getWindow().superDispatchTouchEvent(ev)返回值表示事件在Activity的view中事件是否分发成功,如果为true则事件分发成功(既被Activity中的view所消耗),如果为false,就调用Activity自己的onTouchEvent()方法来处理事件。结合前面2篇文章的分析,可以得到如下的流程图:(下图来源与网络)
Android事件分发之Activity篇 -- dispatchTouchEvent、onTouchEvent之间关系_第2张图片

总结

我们通过对这几篇文章分析Activity、ViewGroup、View各个层级对触摸事件的处理过程可以发现,Android中每个层级对触摸事件的处理都是从dispatchTouchEvent方法开始的,首先先调用下一层级的dispatchTouchEvent方法,将触摸事件传递给下一层级,如果下一层级对触摸事件进行了处理,就可认为本层级也对触摸事件进行了处理,那么本层级就不会对触摸事件进行处理了;如果下一层级没有对触摸事件进行处理,即下一层级的dispatchTouchEvent方法返回false,那么才会调用本层级的onTouchEvent方法对触摸事件进行处理。

你可能感兴趣的:(view)