目录
1、dispathTouchEvent(MotionEvent event)
2、onInterceptouchEvent(MotionEvent ev)
3、onTouchEvent(MotionEvent event)
一、触摸事件分析
任何事物都有一个起点,触摸事件也是如此。当手指触摸手机的屏幕后发生什么呢?首先是由Linux内核调用触摸屏驱动,然后触摸屏驱动通知Android OS 的HAL层的相关Library,最后相关的Library会通知位于应用层的程序。
二、事件分发
事件分发就是对MotionEvent事件的分发过程,当一个MotionEvent事件产出后系统就需要把这个事件传递给一个具体的View,而这个传递的过程就是事件分发。分发过程由这几个方法完成:dispathTouchEvent、onInterceptouchEvent、onTouchEvent。
1、dispathTouchEvent(MotionEvent event)
用来进行事件的分发。如果事件能够传递给当前View,那它一定会会被调用,返回结果受当前View的onTouch和下一级的View的dispathTouchEvent方法的影响,表示是否消耗当前事件。
2、onInterceptouchEvent(MotionEvent ev)
在dispathTouchEvent方法内部调用,用来判断是否拦截某个事件,如果当前View拦截了某个,那在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。
3、onTouchEvent(MotionEvent event)
也是在dispathTouchEvent方法内部调用,用来处理事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接收事件。
4、三个方法的关系
//这个是伪码 不是源码
public boolean dispathTouchEvent(MotionEvent event){
boolean result = false;
if(onInterceptTouchEvent(event)){
result = onTouchEvent(event);
}else{
result = child.dispathTouchEvent(event);
}
return result;
}
通过上面的伪码已经完全表示出它们的关系。
三、关于事件分发机制
1、同一个事件序列是指从DOWN事件开始,中间伴随着数个MOVE事件,最终以UP事件结束。
2、正常的情况下,一个事件序列只能被一个View拦截且消耗。因为一旦一个View拦截了某事件,那么同一个事件序列的内的所有事件都会交给它处理,因此同一个事件中的事件不能分发给两个View的同时处理。
3、某个View一旦拦截了,那么这一个事件序列只能由它处理,且它的onInterceptouchEvent不会调用了。
4、某个View一旦开始处理事件,如果它不消耗DOWN事件,那么同一个事件序列的其他事件都不会交给它了,并且事件将重新交给它的父元素去处理。
5、Viewgroup默认不拦截任何事件。
6、View没有onInterceptouchEvent方法。
7、View的onTouch默认否会消耗事件。
8、事件传递是由外向内的,事件总是先传递给父元素然后由父元素分发给子元素,通过requestDisallowInterceptTouchEvent分发可以在子元素中干预父元素的事件分发的过程,但是DOWN事件除外。
9、事件传递遵循:activity-> window->View。
四、activity中的事件分发
activity的dispatchTouchEvent的源码
publick boolean dispatchTouchEvent(event){
if(event.getAction() == MotionEvent.ACTION_DOWN){
onUserInteraction();
}
if(getWindow().superDispatchTouchEvent(event)){
return true;
}
return onTouchEvent(event);
}
第一步是判断事件如果是点击事件,则调用 onUserInteraction 方法,该方法的方法体为空,可以重写这个方法,用于处理一些交互问题。
第二步是调用了 Window 的 superDispatchTouchEvent 方法,如果返回 true,则表示此事件已被消费,结束此次分发流程,false 则继续调用该 Activity 的 onTouchEvent 方法处理该事件。
如果感觉对您有意义,就给博主一些鼓励(点赞、关注、收藏),如果有错误欢迎大家评论。