简述
1.View对触摸事件的处理机制
2.ViewGroup对触摸事件的处理机制
3.android对触摸体系的概念
4.混合ViewGroup、View的分发拦截机制
1.View对触摸事件的处理机制
View中触摸事件方法有两个:dispatchTouchEvent、onTouchEvent
调用顺序为 :dispatchTouchEvent ——> onTouchEvent
public boolean dispatchTouchEvent(MotionEvent event) {
//省略......
if (mInputEventConsistencyVerifier !=null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}//省略......
if (!result && onTouchEvent(event)) {
result =true;
}
}
//省略
......
return result;
}
2.ViewGroup对触摸事件的处理机制
ViewGrouop中触摸事件方法有三个dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
调用顺序为 :dispatchTouchEvent ——> onInterceptTouchEvent ——> onTouchEvent
// ViewGrouo源码分析
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1); }// 省略
..........if (actionMasked == MotionEvent.ACTION_DOWN ||mFirstTouchTarget !=null) {
final boolean disallowIntercept = (mGroupFlags &FLAG_DISALLOW_INTERCEPT) !=0;
if (!disallowIntercept) { // 如果返回false
intercepted = onInterceptTouchEvent(ev); // 方法传递
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
从源码可以看出来所有触摸事件的触发都是在 dispatchTouchEvent 方法开始的,如果对源码感兴趣的同学可以去看一下哦!
3.android对触摸体系的概念
在android中对触摸事件有两个概念:分发、拦截
注意:在UI中,对触摸事件的处理是从父类开始执行的,首先执行了父类的dispatchTouchEvent 才会去执行子类的 dispatchTouchEvent,遵循先父后子的原则
分发
分发可以理解为传递的意思,是触摸view之后所传递执行事件方法的一种机制:
view: dispatchTouchEvent 方法分发给 onTouchEvent 方法
viewGroup :dispatchTouchEvent 方法分发 给onInterceptTouchEvent方法分发 给 onTouchEvent 方法
分发机制就是调用dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent方法的时候返回值为false
分发可以事件对本身的分发,也可以是向下View(ViewGroup)分发
拦截
拦截可以理解为对该事件停止向下View(ViewGroup)或本身传递触摸事件
拦截机制就是对调用dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent方法的时候返回值为true
拦截事件之后,就不再向下传递消息机制了
混合ViewGroup、View的分发拦截机制
举个例子说明一下。看图
图中有四个View:View A、View B、View C、View D
其中View B和View D是view,View A和View C是ViewGroup
接下来我们对该试图进行触摸事件操作:
1、从 View A 视图开始操作:
我们对 A 试图进行操作,系统首先会调用 dispatchTouchEvent 方法,判断该返回值。如果是 true 则拦截事件,剩下的方法都不会被调用,如果是 false ,则会调用 onInterceptTouchEvent 方法判断返回值。如果是true,则会调用 A 中的 onTouchEvent 方法,如果是 false 则会判断被触摸发该区域是否有子view,发现没有,则同样会调用 A 的 onTouchEvent 方法。
2、从 View B 试图开始操作
我们对B试图进行操作,因为 B 的存在父试图 View A,所以首先android系统会先调用 A 的 dispatchTouchEvent 方法,在该方法进行判断返回值。如果返回 true,剩下的方法不会执行,返回 false,则会调用 A 的 onInterceptTouchEvent方法,判断返回值。如果为true,则调用 A 的 onTouchEvent 方法,如果为 false,则会调用 View B 的 dispatchTouchEvent 方法进行判断,如果返回true,剩下的方法不会调用,直接返回 View A中的 onTouchEvent 方法,如果返回false,因为View B 是 View ,没有 onInterceptTouchEvent 方法,所以直接会调用 onTouchEvent 方法,判断返回值。如果返回true,说明该事件已经被处理,如果返回false,则会调用 父View A 的 onTouchEvent 方法。
3、从 View C 视图开始操作
首先会调用 A 的 dispatchTouchEvent 方法,true剩下的方法不会调用,false调用 A 的 onInterceptTouchEvent 方法判断。true调用 A 的 onTouchEvent 方法,false 调用 C 的 dispatchTouchEvent 方法判断返回值。true返回 A 的 onTouchEvent 方法,false调用 C 的 onInterceptTouchEvent 方法判断。true返回 A 的 onTouchEvent 方法,false调用 C 的 onTouchEvent 方法判断。true调用 A 的onTouchEvent ,false 先判断该视图是否有子View,有就分发机制给子view,没有就返回 A 的 onTouchEvent 方法。
4.从 View D 试图操作
首先执行 3 的操作到 View C试图分发机制到 View D 的 dispatchTouchEvent 方法,true就处理完事件处理返回 View C 的 onTouchEvent 方法再返回到 View A 的onTouchEvent 方法,false 就先返回到 View C 的onTouchEvent 方法再返回到 View A 的 onTouchEvent 方法。
有兴趣的同学可以试一下哦
我说的不是很清晰,希望大神看到可以指正错误