View的事件分发机制

作者: 蝉翅的空响 | 来源:发表于2017-02-04 17:40 被阅读63次

    Android View事件分发机制


    当一个点击事件产生后,他的传递过程遵循Activity->Window->View的逐级传递。我们这里讨论的是在Android系统View里事件传递。

    1 点击事件的传递规则

    点击事件对应Android源码里就是大家常用的MotionEvent。大家知道Android的View是由顶向下的树形结构,有点像HTML的DOM树,点击事件分发就是各层View和ViewGroup对MotionEvent的传递,最终传递到一个具体的View,由他来消费这个MotionEvent.下面介绍事件分发三个重要的方法。

    • boolean dispatchTouchEvent(MotionEvent ev) 用来事件分发,如果事件传递到View这个方法就一定会调用
      返回结果受到当前View和下级View的dispatchTouchEvent影响。
    • boolean onInterceptTouchEvent(MotionEvent ev) 在上面个方法内执行,用来判断是否拦截事件,返回结果表示是否拦截当前事件。
    • boolean onTouchEvent(MotionEvent ev) 在dispatchTouchEvent中调用,用来消费事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View不会再次接受到事件。

    用伪代码来表述就是:

    public boolean dispatchTouchEvent(MotionEvent ev)
     {
         boolean consume=false;
         if (onInterceptTouchEvent(ev)) {
             consume=onTouchEvent(ev);
         }else{
             consume=child.dispatchTouchEvent(ev);
         }
         return consume;
     }
    

    这里需要注意的是事件只有一个,也只有一次消费或者说处理机会。正常情况下,一个事件序列只能被一个View拦截且消耗掉。当一个View需要处理事件时,如果他设置了OnTouchListner,那么OnTouchListner中的onTouch方法就会被回调。这时事件如何处理还要看onTouch的返回值,如果返回false,者onTouchEvent方法会调用;如果返回true,那么onTouchEvent方法不会被调用。所以OnTouchListner的优先级高于onTouchEvent方法。

    无论这个动作是DOWN,MOVE,UP他们的执行顺序是:1、dispatchTouchEvent ; 2、setOnTouchListener的onTouch ; 3、onTouchEvent

    这里在说一下View和ViewGroup在事件传递机制的不同的地方,ViewGroup默认不拦截任何事件。Android源码中的ViewGroup的源码的onInterceptTouchEvent方法默认返回false。而View没有onInterceptTouchEvent方法,一旦有点击事件传递给他,他的onTouchEvent就会调用。

    View的enable属性不影响onTouchEvent的默认返回值。只要他的cliclable或者longClickable有一个为true,那么他的onTouchEvent就返回true。

    特别的一点是事件总是先传递给父元素,然后再有父元素分配给子元素,通过requestDisallowInterceptTouchEvent方法可以在子元素中干预父元素的除ACTION_DOWN外的事件分发过程。

    Android View事件机制 21问21答
    Android View 事件分发机制源码解析(上)
    Android ViewGroup事件分发机制

    相关文章

      网友评论

        本文标题:View的事件分发机制

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