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() 方法