Viewrootimpl 处理事件源码
时间: 2023-09-08 20:08:16 浏览: 40
ViewRootImpl 类是 Android 系统中负责协调视图层级结构与输入事件的重要类。它负责处理应用程序中所有的输入事件,并将它们发送到正确的 View 上进行处理。
下面是 ViewRootImpl 类中处理事件的源码:
```java
private void deliverPointerEvent(MotionEvent event) {
if (event.isTouchEvent()) {
boolean handled = false;
final int action = event.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| actionMasked == MotionEvent.ACTION_POINTER_DOWN
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
// Check for interception.
intercepted = dispatchTransformedTouchEvent(event, false,
null, TouchTarget.ALL_POINTER_IDS);
} else {
intercepted = false;
}
if (!intercepted && mFirstTouchTarget == null) {
// No touch targets so send to the root.
handled = super.dispatchTouchEvent(event);
}
if (!handled && mFirstTouchTarget == null) {
// Send to touch targets.
TouchTarget target = mFirstTouchTarget;
while (target != null) {
if (target.pointerIdBits == TouchTarget.ALL_POINTER_IDS) {
handled = target.child
.dispatchTouchEvent(event);
if (handled) {
break;
}
}
target = target.next;
}
}
}
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}
recyclePointerEvent(event);
}
}
```
该方法主要是判断事件类型,然后根据事件类型分别处理:
1. 如果事件是触摸事件,那么会先检查是否需要拦截事件,如果需要拦截则不会继续往下分发事件。
2. 如果事件是按下事件,或者当前有触摸目标,则会先分发到 ViewRootImpl 自身处理。
3. 如果 ViewRootImpl 自身没有处理该事件,则会将事件分发到当前的触摸目标中,直到有一个触摸目标处理了该事件为止。
其中,触摸目标是指当前被触摸的 View,它是 ViewRootImpl 根据事件坐标找到的最上层的 View。在该方法中,触摸目标是通过遍历 TouchTarget 链表来查找的。每个 TouchTarget 包含了一个触摸目标 View 和该 View 关联的触摸点标识符(pointerIdBits)。
该方法中还包括了一个事件回收的操作,即将 MotionEvent 对象回收到对象池中。这是 Android 系统中常用的一种优化内存的方式,可以避免频繁地创建和销毁对象。