1.view事件传递方向 Activity -> window -> view
2.了解事件传递,必须知道以下三个方法:
①:dispatchTouchEvent事件分发
②:onInterceptTouchEvent 是否拦截
③:onTouchEvent 事件处理
3.通过伪代码先梳理一下他们的关系:
public boolean dispationTouchEvent(MotionEvent event){
if (onInterceptHoverEvent(event)){
return onTouchEvent(event);
} else {
return child.dispatchTouchEvent(event);
}
}
代码描述的很清晰:
①:如果事件不拦截,那么就传递给child的dispatchTouchEvent。
②:如果事件拦截,那么就交给当前onTouchEvent处理。
4.全部默认不拦截情况:
当事件产生,首先Activity 的dispationTouchEvent开始分发,因为默认不拦截,所以传递给window,最后传递给view,注意:view是没有dispationTouchEvent这个方法的,也就是说view不能继续分发,所以onTouchEvent接收这个事件。
我们继续走:默认view的onTouchEvent方法返回false,也就是不处理此事件,那么事件上抛,刚才是window分发事件给view的,所以我们再回抛给他。回抛的路线是这样的:view的onTouchEvent -> window的onTouchEvent -> Activity 的onTouchEvent,如果Activity不处理,那么此事件废掉。
5.出现拦截的情况:
当事件产生,Activity的dispationTouchEvent开始分发,我们假设window会拦截,现在回头看3的伪代码,window的onTouchEvent开始触发,这里有两种情况:
①:如果window的onTouchEvent返回true,那么事件就被window消耗掉。
②:如果window的onTouchEvent返回false,那么事件开始从window的onTouchEvent上抛,就没有view什么事了。
6.我们平常会设置监听,那么如果有了监听事件传递会发生什么变化呢?
①:假设我们给view设置OnTouchListener。
②:那么当事件分发给view之后,注意,事件传递开始发生变化,这时onTouchListener会接收事件而不是onTouchEvent,也就是说OnTouchListener的优先级高于onTouchEvent。
③:当onTouchListener返回false时,那么onTouchEvent接收事件。当onTouchListener返回true时,那么事件被消耗。
到此结束
笔者能力有限,不足之处欢迎指出。
网友评论