View 的事件分发
事件分发的伪代码
1 | boolean dispatchTouchEvent(MomentEvent ev){ |
onTouchEvent()
返回值为 true 代表该 View 要处理这个事件
返回值为 false 代表该 View 不处理该事件,由父容器处理。
onInterceptTouchEvent()
ViewGroup 中的 onInterceptTouchEvent()
方法如果返回 true
,则代表这个 ViewGroup
要拦截这个动作,则 子 View 接收不到这个动作。
dispatchTouchEvent()
该方法的返回值代表是否处理/消费该触摸事件
OnTouchListener
如果对 ViewGroup
设置 TouchListener
,boolean onTouch(MotionEvent ev)
方法的返回值会对事件分发产生影响
- 如果返回 true ,则该 View 的
onTouchEvent()
方法不会被调用,即onInterceptTouchEvent()
方法返回为false
- 如果返回 false ,则该 View 的
onTouchEvent()
方法会被调用
例如
当 ViewGroup
设置了 touchListener
并且 onTouch
方法返回为 true
时
1 | ViewGroupView: onInterceptTouchEvent false |
当返回 false
时
1 | ViewGroupView: onInterceptTouchEvent false |
在事件分发过程中,是自底向上对触摸事件的递归
在触摸事件没有被 ViewGroup 拦截的情况下直到分发到 view 中,会调用 View#dispatchTouchEvent(MotionEvent event)
方法
1 | public boolean dispatchTouchEvent(MotionEvent event) { |
如果 View 设置了 TouchListener
则,且返回的值为 true,则处理 listener 中的代码,否则执行 onTouchEvent(event)
中的代码,并返回 true,告知父View 我已经消费了这个事件
从以上代码也可看出onTouch()
方法优先级高于onTouchEvent(event)
方法」
子 View 要请求父 View 不拦截事件,可以调用 requestDisallowIntercept()
方法