android系统的事件机制主要由boolean dispatchTouchEvent(MotionEvent event)和boolean onTouchEvent(MotionEvent event)实现。
对于View而言,事件的分发流程:dispatchTouchEvent---------->onTouch(如果设置了View的onTouchListener)------------>onTouchEvent----------->各种事件(如单击事件等等)。
首先以一个Button为例分析事件流程,给button设置OnClickListener和onTouchListener当我们点击按钮的时候会发现首先执行的是onTouchListener然后是onClickListener,并且是在ACTION_UP事件执行完成后执行的onClickListener,如果onTouchListener返回true,表明它要自己消费事件,onClickListener就不会被执行;
我们再自定义一个MyButton继承自系统的Button,并且实现onTouchEvent方法,点击按钮时发现如果onTouchListener返回true的话,onTouchEvent是不会执行的,和上述一样,它自己消费,由于OnClickListener是在onTouchEvent被执行的,所有也不会触发。这些事件的控制,其实都源于dispatchTouchEvent方法,这个方法控制的事件的分发与执行。查看dispatchTouchEvent发现只有当该View是enable才可以触发事件:源码如下:
boolean result = false;
if(li!=null && li.onTouchListener != null && (mViewFlags & ENABLE_MASK) == ENABLE && li.onTouchListener.onTouch(this,event)){
result = true;
}
if(!result && onTouchEvent(this,event)){
result = true;
}
其中(mViewFlags&ENABLE_MASK) == ENABLE是判断当前控件是否能enable,如果为false,onTouchListener不会执行,但是onTouchEvent会继续执行,但是里面的onClickListener就不会继续执行了。如果dispatchTouchEvent返回false,则下一个事件就不会被分发了(如在ACTION_DOWN返回false,那么ACTION_MOVE和ACTION_UP就不会执行),onTouchEvent返回值也是如此.
对于ViewGroup要多一个方法boolean onInterceptTouchEvent(MotionEvent event);
dispatchTouchEvent---->onInterceptTouchEvent(如果返回false交给子view的dispatchTouchEvent,如果返回true,则表示拦截事件,交由自己的onTouchEvent处理)余下处理和VIew一样