我们设计的场景实例是(你所在的公司):
- 一个总经理——MyViewGroupA,最外层的ViewGroup
- 一个部长——MyViewGroupA,中间的ViewGroup
- 一个干活的你——MyView,在最底层
本实例的整个布局结构图:
对于Viewgroup来说,需要重写如下所示的三个方法
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
对于View来说,重写如下所示的两个方法
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
对比ViewGroup和View,显然ViewGroup的级别更高,比View多了一个onInterceptTouchEvent的方法。此方法就是事件拦截的核心方法。
正常情况下,事件的传递顺序是:
总经理(MyViewGroupA)——>部长(MyViewGroupB)——>你(MyView)。事件传递的时候先执行dispatchTouchEvent的方法,在执行onInterceptTouchEvent() 的方法事件的处理顺序是:你(MyView)——>部长(MyViewGroupB)——>总经理(MyViewGroupA)。事件处理都是执行onTouchEvent()方法。
事件传递的返回值非常容易理解:True拦截 ,不继续。False不拦截,继续流程。
事件处理的返回值也类似:True处理了,不用审核。false不处理,给上级处理。
由于核心方法是onInterceptTouchEvent()方法,而dispatchTouchEvent()方法是事件分发的第一步,所以省略分发的正常流程图:
如果MyViewGroupA(总经理),觉得此任务太简单了,自己处理了,总经理拦截事件流程图如下:
注:×标示不通,走的是黑线
如果是部长拦截里事件,其图如下:
如果走到MyView后,onTouchEvent()方法返回True,说明myView自己处理了事件。其事件处理流程图如下:
如果MyView向上汇报给MyViewGroupB(部长),但是部长自己处理掉了,没有向上汇报,其流畅图如下:
注:不好意思,每张图右半边,MyView和MyViewGroupB中间是onTouchEvent()方法,写错了。