总结一下Android事件分发的机制

时间:2022-12-30 23:39:50

以前对Android的事件分发一直都不是很熟悉,所以找了个时间 仔细研究了一下android源码终于把困扰我多时的问题解决了

首先 我们假设一个场景  一个LinearLayout 里面放入一个Button 那么事件怎样分发的呢,


Button继承自TextView 而TextView继承自View 当Button点击的时候 会从 父布局向上查找 dispatchTouchEvent方法进行处理,当然我们也可以自定义一个LinearLayout

然后重写其中的dispatchTouchEvent方法 如果没有重写 父布局会一层层向上级布局查找,最后我们可以在ViewGroup中找到这个方法 查看这个方法的源码可以发现

进入此方法以后首先执行的是一个if条件判断

if (disallowIntercept || !onInterceptTouchEvent(ev)) 

判断的条件第一个条件默认为false  当第二个条件为true时  就可以进入if的内部执行

onInterceptTouchEvent 这个 方法大家应该都不陌生,当此方法的返回值为false时 就会进入 if内部 查看内部的代码 可以得知 if内部主要 就是判断view是否被点击

当被点击后会执行view的dispatchTouchEvent方法   此方法虽然和ViewGroup的dispatchTouchEvent方法名称相同 但是其中的代码却完全不同  

public boolean dispatchTouchEvent(MotionEvent event) {
    if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
            mOnTouchListener.onTouch(this, event)) {
        return true;
    }
    return onTouchEvent(event);
}

view的此方法较简单 通过分析我们可以看出  返回值为true 需要满足三个条件

1,相应的View设置了onTouchListener

2. 当前的view是可以点击的  Button默认是可以点击的 但是当我们点击的对象是ImageView的时候 就不同了此种情况需另考虑

3.第三个就是onTouch的返回值 当此方法的返回值为true时  会直接返回true 返回值为false时  会执行 onTouchEvent方法 此方法的内部 执行了onClick方法


总结一下:


当我们点击一个View的时候 会先从它的父布局中查找dispatchTouchEvent方法   找到此方法后 会判断onInterceptTouchEvent 当此返回值为false时 会执行view的dispatchTouchEvent的方法  进入此方法以后 会判断 是否设置了onTouchListener方法 和onTouch方法的返回值 如果没有设置监听或者返回值为false 则会执行onTouchEvent方法方法中封装了onClick方法 就会执行