Touch 事件相关方法 | 方法功能 |
ViewGroup |
Activity View |
public boolean dispatchTouchEvent(MotionEvent ev) | 事件分发 |
Yes | Yes Yes |
public boolean onInterceptTouchEvent(MotionEvent ev) |
事件拦截 |
Yes | No No |
public boolean onTouchEvent(MotionEvent ev) | 事件响应 |
Yes | Yes Yes |
一、view的事件分发
搞清楚下面几个方法关系就ok了,相对ViewGroup的分发还比较简单
dispatchTouchEvent、onTouchEvent、onTouch
view的源码:
看view的分发代码
第一个条件 mOnTouchListener是在setOnTouchListener方法里赋值的,也就是说只要我们给控件注册了touch事件,mOnTouchListener就一定被赋值了。第二个条件(mViewFlags & ENABLED_MASK) == ENABLED是判断当前点击的控件是否是enable的,按钮默认都是enable的,因此这个条件恒定为true。
第三个条件就比较关键了,mOnTouchListener.onTouch(this, event),其实也就是去回调控件注册touch事件时的onTouch方法。也就是说如果我们在onTouch方法里返回true,就会让这三个条件全部成立,从而整个方法直接返回true。如果我们在onTouch方法里返回false,就会再去执行onTouchEvent(event)方法。
其实大致就是这样,触摸一个view就会先有Down事件,然后执行dispatchTouchEvent(),而如果注册onTouch接口监听,那么他其实最先会调用onTouch方法而不是onTouchEvent。若是onTouch返回true那就没有onTouchEvent什么事了,而若是false就会去调用onTouchEvent方法了,若是onTouchEvent返回true,dispatchTouchEvent也会返回true,就代表该view消费了此事件,接下来的Move、Up事件也会有他处理,若是onTouchEvent返回false,则dispatchTouchEvent也会返回false,于是就会把事件还给上一级view的onTouchEvent,接下来就不重要了,因为这只讲view的分发。然后要说的就是比如类似onClick这些方法,都是接口回调嘛,这些也就是在onTouchEvent里面调用的,具体自己看源码,所以这也就说明onTouch先于onClick执行。
二、ViewGroup事件分发(这个很乱,待续)
1.相关方法分发逻辑
dispatchTouchEvent
*return super.dispatchTouchEvent(ev):事件自动分发给当前view的onInterceptTouchEvent或者onTouchEvent
*return true:事件停止向下传递,并分发给当前view由dispatchTouchEvent进行消费
*return false:事件停止向下传递,返回给上一级的onTouchEvent
onInterceptTouchEvent
*return super.onInterceptTouchEvent(ev):事件默认被拦截,将事件交由当前view的onTouchEvent进行处理
*return true:拦截掉子view的事件,将事件交由该view的dispatchTouchEvent进行处理
*return false:事件放行,当前view上的事件会传到子view,再由子view的dispatchTouchEvent进行分发
onTouchEvent
*return super.onInterceptTouchEvent(ev):默认处理事件的逻辑和返回 false 时相同
*return true:表示它是真正要处理这次请求的View,之后的Aciton_UP和Action_MOVE将由它处理
*return false:事件从当前view向上传递,并且都由上层view的onTouchEvent接收,如果都返回false,则这个事件会 消失,就接收不到下一次事件。
2. dispatchTouchEvent
ViewGroup的dispatchTouchEvent方法真正执行分发工作,,而view的dispatchTouchEvent不再分发,直接决定是否把事件交给自己处理。