Android事件分发摘要
点击事件MotionEvent到达顶级DecorView后,会调用dispathTouchEvent()方法,然后逻辑是这样的:如果顶级ViewGroup拦截事件onInterceptTouchEvent()返回true,则事件由ViewGroup处理,这时如果ViewGroup的mOnTouchListener被设置,则onTouch()会被调用,否则onTouchEvent()会被调用。也就是说都提供的话,onTouch()会屏蔽掉onTouchEvent()。在onTouchEvent()方法中,如何设置了mOnClickListener,则onClick()会被调用。如果顶级ViewGroup不拦截事件,则事件会传递给它所在的点击事件链上的子View,这时子View的dispathTouchEvent()方法会被调用。到此为止,事件已经从顶级View传递给了下一层View,接下来的传递过程和顶级View是一致的,如此循环,完成整个事件的分发。
ViewGroup在两种情况下会判断是否要拦截当前事件:事件类型为ACTION_DOWN或者子View成功处理了当前事件。
一旦ACTION_DOWN事件由父ViewGroup拦截,则后续的ACTION_MOVE和ACTION_UP都交给父ViewGroup处理,不会再传递给子View了。
ACTION_DOWN事件传递给子View,但是子View没有成功处理—onTouchEvent()返回false,则会重新调用父ViewGroup的dispathTouchEvent(),由于子View没有成功处理当前事件,不会再调用父ViewGroup的拦截方法onInterceptTouchEvent(),而是直接调用父ViewGroup的onTouchEvent()方法,后续的事件直接由父ViewGroup处理了,不会再传递给子View了。
总结:事件分发中经常用到的方法dispatchTouchEvent()、onInterceptTouchEvent()、
onTouch()、
onTouchEvent()、
onClick()、
onDispatchTransformedTouchEvent()、
resetTouchState()、
addTouchTarget()、
requestDisallowInterceptTouchEvent()
图文无关