Android事件分发备忘

作者: oceanLong | 来源:发表于2017-10-19 01:08 被阅读28次

    前言

    事件的分发是面试的必考题,也是Android作为一个移动系统,与用户交互的基础。由于整个事件分发比较繁杂,这里做一个总结,以作备忘。

    事实上,Android系统中的事件分发机制是一个委托者模型。我们先从最简单的看起。

    三个方法

    在Android的摸触事件中,我们通常关注的方法有三个。

    dispatchTouchEvent(MotionEvent event)
    onInterceptTouchEvent(MotionEvent event)
    onTouchEvent(MotionEvent event)
    

    这个三个方法组成了Android系统中,各个层级的事件分发,拉截和处理。


    我们先从最熟悉的讲起:

    View

    View 作为视图层级中的最上层。是事件分发的终点

    dispatchTouchEvent

    View 的 作为最上层的控件,事件不再需要分发,因此,在dispatchTouchEvent中,几乎一定会调用 View 本身的 onTouchEvent(排除enable被关闭),同时将onTouchEvent的返回结果return。

    onTouchEvent

    在onTouchEvent中,Android实现了View的点击拖动等事件。

    onInterceptTouchEvent

    由于View 作为最上层视图不会再向更上层传递事件,所以没有onInterceptTouchEvent 方法。


    ViewGroup

    ViewGroup 作为视图层级中View的父控件。是事件分发的中间环节

    dispatchTouchEvent

    ViewGroup 的 作为中层的控件,不仅需要接收底层的事件(底层会调用ViewGroup的dispatchTouchEvent方法),还要将事件分发到上层,因此,在dispatchTouchEvent中,ViewGroup需要优先考虑onInterceptTouchEvent,如果事件被拦截,则直接调onTouchEvent,如果未被拦截,就需要调用所有子View的dispatchTouchEvent。

    onTouchEvent

    ViewGroup继承了View的onTouchEvent。有两种情况,ViewGroup的onTouchEvent方法会调用。

    1. ViewGroup的onInterceptTouchEvent返回true,表示ViewGroup决定拦截这个事件。
    2. ViewGroup的所有ChildView的onTouchEvent全部返回false,此时表示,没有任何一个ChildView愿意处理这个事件。所以,事件会返回给上层ViewGroup。同理,如果ViewGroup不处理这个事件,返回false,事件会继续往上传。
    onInterceptTouchEvent
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
                    && ev.getAction() == MotionEvent.ACTION_DOWN
                    && ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
                    && isOnScrollbarThumb(ev.getX(), ev.getY())) {
                return true;
            }
            return false;
        }
    

    返回true表拦截,false不拉截。

    一图流:


    看了上面的图,关于事件传递的所有疑惑应该都不存在了。接下来我们来探讨一下,事件分发的最上层是什么。

    其实从上图中我们就可以看到,最上层的是Activity,Activity中有dispatchTouchEvent和onTouchEvent方法。因为Activity处于最上层,所以不存在拦截的问题。dispatchTouchEvent和onTouchEvent与ViewGroup的流程相同。


    这里补充一点小小的信息。Activity与View的关系。同样是一图流:

    以上。

    相关文章

      网友评论

        本文标题:Android事件分发备忘

        本文链接:https://www.haomeiwen.com/subject/jzzruxtx.html