浅谈android应用之事件分发

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/angelsmiling/article/details/102696938

1. 前言

在android中,事件有多种种类,比如说最常见的屏幕的点击事件,除此之外,还有外接设备的信号事件,如鼠标,键盘,遥控器的信号事件。这里就拿最常见的屏幕的点击事件来说事。点击屏幕的时候,首先是硬件驱动采集点击屏幕时候的信息,硬件驱动采集到了之后,它本身不会做消费这些数据信息,它会往native层抛出这些信息,但最终native层会将这些信息再抛往上层framework层进行处理。这个过程可以研究系统服务IMS,这里不再详述。

到这一步,就到了我们通常所述的事件分发,即应用层的事件分发的过程。

2. 流程图

以下是事件分发的流程图,先大体看看在应用层事件分发与事件被消费的过程:
在这里插入图片描述
可以看出整个流程呈现出U型状,可以大体总结出事件是往下分发,往上消费,接下来将对这个过程进行详细分析。

3. Activity

点击事件在应用层首先到Activity上,所以我们从Activity的分发方法看:

=============/frameworks/base/core/java/android/app/Activity.java ===============

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

1.如果是down,说明是一个新的事件,初始化UI(空实现方法,没有太大实际意义)

2.调用PhoneWindow的superDispatchTouchEvent 方法,把事件从Activity 分发到PhoneWindows,再到DecorView,再到ViewGroup,View,如果中间不被中断拦截的正常情况下。(这个过程是事件分发核心方法,这个可以结合我的文章视图原理辅助理解)如果子View没有消费该事件,则调用自身的onTouchEvent尝试处理。

3.如果上面分发过程都没有消费事件,则最终由Activity的onTouchEvent方法消费事件。

4. ViewGroup

ViewGroup的分发方法主要作用是确定那个View消费事件

1.判断是否进行事件拦截,

2.根绝拦截方法的返回结果进行处理

如果进行了拦截,则会调用到super.dispatchTouchEvent(event),最终会调用到View类的dispatchTouchEvent(event)

如果没有进行拦截,则会对自己内部的所有子View进行判断,是否有焦点,是否在事件坐标范围之内等等一系列,然后调用该View的dispatchTouchEvent(event)(这里补充一下,这个子View可以是ViewGroup类型的也可以是View类型的。所以如果是viewGroup类型的还会把这个流程走一遍,直到找到我们需要的View)

还需要注意的是事件传递在viewgroup这个过程才有拦截事件的方法!

5. View

View类型的分发方法和ViewGroup的作用不一样,主要是确定怎么消费事件

判断mOnTouchListener.onTouch(this, event)的返回值,如果返回true,后边onTouchEvent(event)就不会响应了,如果返回false,则会调用自身onTouchEvent(event)消费事件,如果onTouchEvent返回false,则回到上以及viewgroup的onTouchEvent进行处理,以此类推,直到最后事件被消费。

猜你喜欢

转载自blog.csdn.net/angelsmiling/article/details/102696938