赞
踩
所谓点击事件的事件分发,就是对MotionEvent事件的分发过程,传递给某一个View.
在事件传递中有三个方法是贯穿始终的
dispatchTouchEvent()
:进行事件的分发 如果事件能传递到View那么此方法一定会被调用,返回值受当前View的onTouchEvent()
和下级View的dispatchTouchEvent()
的影响. 表示是否消耗当前事件.onInterceptTouchEvent()
: 判断是否拦截事件,如果当前View拦截了某个事件,那么在同一个事件序列中, 此方法不会被再次调用, 返回结果表示是否拦截当前事件.onTouchEvent()
: 在dispatchTouchEvent中被调用. 用来处理点击事件, 返回结果表示是否消耗当前事件,如果不消耗, 则在同一个事件序列中, 当前View无法再次接收到事件.如果把源码中的各种判断去掉, 只留最核心的代码, 那么就如下:
public boolean dispatchTouchEvent(MotionEvent event) { boolean consume = false; //表示这个事件最终的处理结果 if (onInterceptTouchEvent(event)){ //事件被拦截自己处理 consume = onTouchEvent(event); }else{ //事件被分发到子view的dispatchTouchEvent()中 consume = child.dispatchTouchEvent(event); } return consume; }
OnTouchListener() , onTouchEvent() , OnClickListener() 的优先级
上面说了普遍情况下的事件分发. 如果这个View同时还添加了OnTouchListener
和OnClickListener
. 此时的优先级如下:
OnTouchListener –> onTouchEvent –> OnClickListener
而onTouchEvent()
能否被最终调用取决于设置了OnTouchListener()中的onTouch()
的返回值, 如果onTouch()
返回的结果是false,那么onTouchEvent()
会被调用. 如果返回true那么onTouchEvent()
不会被调用.
而最后被调用的OnClickListener()
方法是在onTouchEvent()
被调用的. 所以如果onTouchEvent()
方法如果执行, 那么对应的添加的onClickLisener()
才会被调用. 所以如果在OnTouchListener()中的onTouch()返回true
那么onTouchEvent()不会被调用,内部调用OnClickListener也就更无法被调用
.
一个事件的传递过程遵循如下
Activity -> Window ->decor view->ViewGroup-> View
如果事件一直不拦截,传递到了最里层的View而最里层的View的onTouchEvent()
也返回false不消费, 那么事件就会向上级的onTouchEvent()
传递,如果还返回false就依次传递.
对于事件机制的规则:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。