View 的事件分发

事件分发的伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
boolean dispatchTouchEvent(MomentEvent ev){
boolean consume = false;
if(onInterceptTouchEvent(ev)){
//该 View 进行拦截
consume = onTouchEvent(ev);
}else{
consume = child.dispatchTouchEvent(ev);
}

returen consume;

}

onTouchEvent()

返回值为 true 代表该 View 要处理这个事件
返回值为 false 代表该 View 不处理该事件,由父容器处理。

onInterceptTouchEvent()

ViewGroup 中的 onInterceptTouchEvent() 方法如果返回 true,则代表这个 ViewGroup 要拦截这个动作,则 子 View 接收不到这个动作。

dispatchTouchEvent()

该方法的返回值代表是否处理/消费该触摸事件

OnTouchListener

如果对 ViewGroup 设置 TouchListenerboolean onTouch(MotionEvent ev) 方法的返回值会对事件分发产生影响

  • 如果返回 true ,则该 View 的onTouchEvent() 方法不会被调用,即 onInterceptTouchEvent() 方法返回为 false
  • 如果返回 false ,则该 View 的 onTouchEvent() 方法会被调用

例如

ViewGroup 设置了 touchListener 并且 onTouch 方法返回为 true

1
2
3
ViewGroupView: onInterceptTouchEvent false
ViewGroupView: dispatchTouchEvent true
ViewGroupView: dispatchTouchEvent true

当返回 false

1
2
3
ViewGroupView: onInterceptTouchEvent false
ViewGroupView: onTouchEvent false
ViewGroupView: dispatchTouchEvent false

在事件分发过程中,是自底向上对触摸事件的递归

在触摸事件没有被 ViewGroup 拦截的情况下直到分发到 view 中,会调用 View#dispatchTouchEvent(MotionEvent event) 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public boolean dispatchTouchEvent(MotionEvent event) {
//忽略
boolean result = false;
//忽略

if (onFilterTouchEventForSecurity(event)) {
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
result = true;
}
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}

if (!result && onTouchEvent(event)) {
result = true;
}
}

//忽略

return result;
}

如果 View 设置了 TouchListener 则,且返回的值为 true,则处理 listener 中的代码,否则执行 onTouchEvent(event) 中的代码,并返回 true,告知父View 我已经消费了这个事件

从以上代码也可看出onTouch() 方法优先级高于onTouchEvent(event) 方法」

子 View 要请求父 View 不拦截事件,可以调用 requestDisallowIntercept() 方法

作者

PPTing

发布于

2023-07-23

更新于

2024-05-24

许可协议

评论