美文网首页
Android View的事件体系(二)——分发响应机制

Android View的事件体系(二)——分发响应机制

作者: 聽媽媽的话 | 来源:发表于2017-10-16 21:06 被阅读16次

所谓点击事件的事件分发,其实就是对MotionEvent事件的分发过程,即当一个MotionEvent产生了以后,系统需要把这个事件传递给一个具体的View的这个过程。点击事件的分发过程由三个很重要的方法共同完成:

  • public boolean dispatchTouchEvent( MotionEvent ev )
    如果事件能够传递到当前View,则此方法一定会被调用。返回结果受当前View的onTouchEvent和下级View的dispatchTouchEvent方法影响,表示是否消耗当前事件。
  • public boolean onInterceptTouchEvent( MotionEvent ev )
    ViewGroup特有的方法,在dispatchTouchEvent方法中调用,用来判断是否拦截某个事件,默认为false,如需拦截则需要重写该方法。
  • public boolean onTouchEvent( MotionEvent ev )
    在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件。

用伪代码来表示三者的关系:

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

        return consume;
    }

简单描述一下点击事件的传递过程:
当一个点击事件产生后,它的的传递过程遵循如下吮吸:Activity->Window->顶级View,顶级View一般都是一个ViewGroup,接收到事件后,就按照事件分发机制去分发事件。
当ViewGroup接收到事件后,它的dispatchTouchEvent就会被调用,如果这个ViewGroup的onInterceptTouchEvent方法返回true,则表示它要拦截当前事件,接着事件就会交给这个ViewGroup处理,即它的onTouchEvent方法就会被调用,事件不再往下分发。如果这个ViewGroup的onInterceptTouchEvent方法返回false,就表示它不拦截当前事件,事件就会被传递到它的子元素去处理,如此反复直到事件被最终处理。具体流程如下:

界面示例.png 事件分发及响应流程.png

值得注意的是:

  • View的onTouchEvent默认都会消耗事件(返回true),除非它是不可点击的(clickable和longClickable同时为false)。View的longClickable属性默认都为false,clickable属性要分情况,比如Button的clickable默认为true,TextView的clickable默认为false。
  • View的enable属性不影响onTouchEvent的默认返回值,哪怕一个View是disable状态的,只要它的clickable或者longClickable有一个为true,即该View是可点击的,它的onTouchEvent都返回true。
  • 在一个点击链里面,只要ViewGroup不拦截事件,则必然是子View先响应,子View不消耗该事件时,ViewGroup才响应。
  • 在同一个ViewGroup里面,多个View若是重叠,且点击的位置在重叠区域,则必最外的View必先响应,该View不消耗该事件时,下层的View才响应。

结合郭霖大神的源码解析,可以更清晰地理解View的分发响应机制:
Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

相关文章

网友评论

      本文标题:Android View的事件体系(二)——分发响应机制

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