详解Android触摸事件处理程序
在了解触摸时间处理程序之前,我们来了解这几个主角:
dispatchTouchEvent(MotionEvent ev)
:此方法允许 ViewGroup 在分派之前截获所有触摸事件onInterceptTouchEvent(MotionEvent ev)
:此方法允许 ViewGroup 监视分派给子视图的事件onTouchEvent(MotionEvent ev)
: 在发生触摸屏运动事件时调用
接下来展示一下工作界面,注意,Layout03
是嵌套在Layout02
里面的
首先,按下Layout03
,事件流程如图所示:
按下的时候总共有触发两个事件:ACTION_DOWN
和ACTION_UP
,但是因为整个事件流程中并没有哪个组件消费了ACTION_DOWN
事件,而只有在onTouchEvent
中消费了ACTION_DOWN
事件,后续事件ACTION_UP
,ACTION_MOVE
...才会触发,所以这里ACTION_DOWN
事件一路挥歌直下,ACTION_UP
则并没有发生。
我们让Layout02
的onTouchEvent
返回true
,消费ACTION_DOWN
事件,事件流程如图所示:
可以看到Layout02
的onTouchEvent
消费ACTION_DOWN
事件之后便不在往下传了,后续事件也随后开始出现,并且Layout02
直接将后续事件派发给消费者。所以当一个组件消费了ACTION_DOWN
事件时,后续事件从窗口传到该组件的dispatchTouchEvent
之后便直接交给它的onTouchEvent
方法处理
我们在Layout02
的onInterceptTouchEvent
里返回true
,事件流程如下:
这时候事件传递就会发生截断的情况,ACTION_DOWN
经过Layout02
的onInterceptTouchEvent
时被强制直接交给自己的onTouchEvent
继续传递。此时如果Layout01
的onTouchEvent
消费此事件:
则后续事件就直接传递给Layout01
的onTouchEvent
处理了,如果让Layout02
的dispatchTouchEvent
直接返回true
呢? 这种情况下
ACTION_DOWN
流经Layout02
的dispatchTouchEvent
时就很干脆的断了,后续事件在Layout02
的dispatchTouchEvent
就直接派发给自己的onTouchEvent
处理,相当于Layout02
在说:我不往下派发了,直接交给我来处理吧!
还有些比较极端的情况:如果让Layout03
的onTouchEvent
来消费ACTION_DOWN
事件,后续事件在流经Layout02
的dispatchTouchEvent
的时候就返回了true
呢? 如图所示,后续事件在
Layout02
的dispatchTouchEvent
就消失了,不再往下传递,Layout03
也就接收不到ACTION_UP
,ACTION_MOVE
之类的后续事件了。最后,如果不在Layout02
的dispatchTouchEvent
返回true
,而是在它的onInterceptTouchEvent
返回呢? 这时候事件到达
Layout02
的onInterceptTouchEvent
之后就变成了ACTION_CENCEL
,直到传递给消费者。