Activty
boolean dispatchTouchEvent(MotionEvent event)
这个方法的决定事件是否向下分发,返回值表示是否消费这个事件。 无论是返回true还是false,事件都到此结束,'不会'向下分发(因为没有调用super.dispatchTouchEvent)
boolean onTouchEvent(MotionEvent event)
1,事件分发过程中,没有ViewGroup或View在其onTouchEvent中return ture最终会回到这里。 2,ViewGroup中拦截事件不会影响这里。
ViewGoup
boolean dispatchTouchEvent(MotionEvent event)
returns: True if the event was handled by the view, false otherwise. 事件ACTION_DOWN 时: 无论是返回true还是false,此次事件及后续事件都不会向下(View/下层ViewGroup)分发 返回true :处理这个事件,会收到后续的ACTION_MOVE,ACTION_UP等,事件不会向上传递(Activity/上层ViewGroup) 返回false:不处理这个事件,不会再收到后续事件;事件会向上传递
boolean onInterceptTouchEvent(MotionEvent event)
Returns: Return true to steal motion events from the children and have them dispatched to this ViewGroup through onTouchEvent(). The current target will receive an ACTION_CANCEL event, and no further messages will be delivered here. 1,这个方法是事件拦截,所以前提是有事件可以拦截。 所以具有'命中View'且'命中View'在ACTION_DOWN时返回true(即具有子View想要接收后续事件)时,这个方法才有使用的价值 2,在ACTION_DOWN时返回true,ACTION_DOWN事件不会传递到子View。 3,这个方法中,任何事件返回true,子View都只会收到一个ACTION_CANCEL,不会再收到其他事件的回调。 4,这个方法中,任何事件返回true,本类的onTouchEvent会收到后续事件。
boolean onTouchEvent(MotionEvent event)
Returns: True if the event was handled, false otherwise. 1,ACTION_DOWN时返回true,可以收到后续事件 2,ACTION_DOWN时返回false,能否收到后续事件,取决有'命中View'是否返回true和onInterceptTouchEvent()是否拦截 3,任何事件返回true,表示此事件已被处理,不会再向上层传递(Activity 或上层ViewGruop中的 onTouchEvent() )
View
boolean dispatchTouchEvent(MotionEvent event)
Returns: True if the event was handled by the view, false otherwise. 1,返回true,此次事件已被处理,不会再向任何地方传递。 2,返回false,不处理此次事件。如果是ACTION_DOWN,那么不会再接收后续事件。
boolean onTouchEvent(MotionEvent event)
Returns: True if the event was handled, false otherwise. 1,ACTION_DOWN时返回true,可以收到后续事件;返回false,不再接收后续事件; 2,返回true事件不再向上传递(上层ViewGoup\Activity)
小结
- dispatchTouchEvent 事件分发,返回true,事件结束。
- onInterceptTouchEvent 事件拦截,返回true,不向下分发(包括自己的onTouchEvent)
- onTouchEvent 事件处理,返回true,不向上传递
图例
一个没有任何消费和拦截的点击事件的传递情况如下图所示:
其他情况请参考下面的尾部链接
其他:
自定义ViewGroup:
一般需要重写onInterceptTouchEvent和onTouchEvent。
如果要处理滑动事件,
- 在onInterceptTouchEvent的ACTION_MOVE中进行拦截,因为如果在ACTION_DOWN中拦截会导致子View失去所有事件。
- 在onTouchEvent的ACTION_DOWN要返回true,因为如果点击没有命中任何View或命中的View 没有处理onTouchEvent,那么就收不到后续事件。
自定义View:
重写onTouchEvent即可。