dispatchTouchEvent
return true:表示该View内部消化掉了所有事件
return false:表示事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费
return super.dispatchTouchEvent(ev):默认事件将分发给本层的事件拦截onInterceptTouchEvent方法进行处理(只有返回super.dispatchTouchEvent(ev)才会触发onInterceptTouchEvent)
onInterceptTouchEvent
return true:表示将事件进行拦截,并将拦截到的事件交由本层控件的onTouchEvent进行处理
return false:表示不对事件进行拦截,事件得以成功分发到子View
return super.onInterceptTouchEvent(ev):默认表示不拦截该事件,并将事件传递给下一层View的dispatchTouchEvent
onTouchEvent
return true:表示onTouchEvent处理完事件后消费了此次事件
return fasle:表示不响应事件,那么该事件将会不断向上层View的onTouchEvent方法传递,直到某个View的onTouchEvent方法返回true
return super.dispatchTouchEvent(ev):表示不响应事件,结果与return false一样
Activity-Window-View。从上到下依次传递,当然了如果你最低的那个view onTouchEvent返回false 那就说明他不想处理 那就再往上抛,都不处理的话
如果某一个子View处理了Down事件,那么随之而来的Move和Up事件也会交给它处理。但是交给它处理之前,父View还是可以拦截事件的,如果拦截了事件,那么子View就会收到一个Cancel事件,并且不会收到后续的Move和Up事件。
传递细节描述
- 事件从 Activity.dispatchTouchEvent() 开始传递, 依次通过getWindow().superDispatchTouchEvent(event)、mDecor.superDispatchTouchEvent(event) 传递,即从Activity-> PhoneWindow ->DecorView, DecorView 是整个 ViewTree 的顶层 ViewGroup ;
- 在整个 ViewGroup 中,事件从顶层开始,依次往子View传递;
父 ViewGroup 可以通过 onInterceptTouchEvent() 对事件做拦截,阻止其往下传递;
如果未被拦截,则子 View 可以通过 onTouchEvent() 消费(处理)事件; - 如果事件从上往下传递过程中一直没有被拦截,且最底层子 View 没有消费事件,事件会反向往上传递,这时父 ViewGroup 可以在 onTouchEvent() 中消费该事件,如果还是没有被消费的话,最后会到 Activity 的 onTouchEvent() 函数;
- 底层View是具有事件的优先消费权的;
- 如果View 没有对 ACTION_DOWN 进行消费,此次点击的后续事件不会传递过来;
- 如果 View 消费了 ACTION_DOWN ,此次点击的后续事件会直接给这个 View,这里的后续事件指的是 ACTION_MOVE 和 ACTION_UP 事件;此时,其父 ViewGroup 的 onIntercept 函数仍会被调用,仍能进行拦截,但它自己的 onIntercept 不会被调用了;
- 子 View 可以在 onTouchEvent 中调用 getParent().requestDisallowInterceptTouchEvent(true),这样父 ViewGroup 的 onIntercept 在后续的事件中就不会被调用了;
- 如果第一个事件即 ACTION_DOWN 就被父 ViewGroup 拦截了,子 View 将不会获取到消费事件的机会;
- OnTouchListener 优先于 onTouchEvent() 对事件进行消费;
消费指的是相应的函数返回 true ; - ViewGroup 才有 onIntercept 方法,View 是没有的,即View不可以拦截事件;
- 所有的事件处理过程都是以 ACTION_DOWN 开始,ACTION_UP 或者 ACTION_CANCEL 结束,ACTION_UP 是事件正常处理逻辑的结束标志,ACTION_CANCEL 是由父 ViewGroup 主动发出,当父 ViewGroup 拦截了除 ACTION_DOWN 之外的事件,会给正在消费 ACTION_DOWN 并等待后续事件的子 View 发送一个 ACTION_CANCEL 事件,通知子 View 结束自己的事件等待;
例:很多小伙伴在第一次使用手势监听的时候,肯定会遇到GestureDetector无效的情况,那么究竟是为什么呢?
当你实现GestureDetector.OnGestureListener接口时,最好重写onDown() 方法,并且使其的返回值为true,这是因为所有手势都以onDown() 消息开头。
当一个 ViewGroup 接收到一个事件的时候,首先会调用 dispatchTouchEvent() 方法进行事件分发,如果 onInterceptTouchEvent() 返回 true,则代表当前 View 会拦截事件,则直接回调 onTouchEvent() 方法进行事件处理。如果不拦截,则直接回调子 View 的 dispatchTouchEvent() 方法,如此反复,一直到最里面的子 View。
当一个点击事件产生后,它的传递过程遵循以下顺序:Activity => Window => View,即事件总是先传递给 Activity,Activity 再传递给 Window,最后 Window 再传递给顶层 DecorView,然后遵循上面的方式一直在最里层 View。
而处理事件则从最里层 View 不断回传给自己的外层 View,如果一直没有 View 进行处理,则直接会回传到 Activity 中。
网友评论