View的事件分发机制

来源:互联网 发布:顾城之死 知乎 编辑:程序博客网 时间:2024/06/01 10:32

要想控制View对点击事件的响应,就需要了解View的事件分发机制。而View的事件分发机制无非就是研究复写下面三个方法,只要明白它们的作用原理,就可以随心所欲的写出满足自己意愿的交互代码:

1.dispatchTouchEvent
View有一个方法叫dispatchTouchEvent,这个方法用于进行事件的分发,只要点击事件传到了这个View,那么这个方法就会被调用。
这个方法的伪代码是:

public boolean dispatchTouchEvent(MotionEvent e){    if(onInterceptTouchEvent(e)){        return onTouchEvent(e);    }else{        return child.dispatchTouchEvent(e);    }}

由此来看,这个方法是用来分发事件,如果自身onInterceptTouchEvent返回false,会把事件传给child。

2.onInterceptTouchEvent
这个方法只有ViewGroup有,View没有。表明当前ViewGroup是否拦截事件,如果返回true拦截,那么会继续走自己的onTouchEvent;如果返回false不拦截,会去调child view的dispatchTouchEvent。

3.onTouchEvent
这个方法表明是否会消耗事件,如果返回true消耗,那么事件分发到此终止;如果返回false不消耗,那么会去调用父容器的onTouchEvent。由于View没有onInterceptTouchEvent,所以只要事件传到View,一定会调onTouchEvent。

有时我们会给一个View设置setOnTouchListener和setOnClickListener,这俩个与前面几个方法的优先级是:
dispatchTouchEvent > onInterceptTouchEvent > onTouch > onTouchEvent > onClick
所以如果在OnTouchListener的onTouch方法return了true,那么onTouchEvent就不会再执行。


比如下图一个LinearLayout里面有一个Button:

点击Button,分几种情况讨论:
1. 如果只想让Button响应:无需重写上述方法;
2. 如果既想让Button响应、又想让LinearLayout响应:使Button的onTouchEvent方法返回false;
3. 如果只想让LinearLayout响应:使LinearLayout的onInterceptTouchEvent方法返回true;
4. 如果想让二者都不响应:复写LinearLayout的dispatchTouchEvent方法(返回true或false皆可)。

0 0
原创粉丝点击