ViewGroup dispatchTransformedTouchEvent 源码解析
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
final boolean handled
//保存原始action ,event状态恢复
final int oldAction = event.getAction()
if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {
event.setAction(MotionEvent.ACTION_CANCEL)
// 取消事件的单独处理,不用做任何过滤或转换
if (child == null) {
handled = super.dispatchTouchEvent(event)
} else {
handled = child.dispatchTouchEvent(event)
}
event.setAction(oldAction)
return handled
}
// 屏幕中所有的`pointer id`
final int oldPointerIdBits = event.getPointerIdBits()
final int newPointerIdBits = oldPointerIdBits & desiredPointerIdBits
if (newPointerIdBits == 0) {
return false
}
final MotionEvent transformedEvent
if (newPointerIdBits == oldPointerIdBits) {
// 如果新的事件和旧的事件的getPointerIdBits & desiredPointerIdBits相同,则设置offsetLocation并且直接去进行事件的分发
// 单点触摸事件会进行这里
// 应用过位移、缩放、旋转之类
// 属性动画移动一个 View 后,目标位置还可以响应触摸事件
// hasIdentityMatrix 是否单位矩阵, 是:未经过位移、缩放、旋转;
if (child == null || child.hasIdentityMatrix()) {
if (child == null) {
handled = super.dispatchTouchEvent(event)
} else {
// 转换成子View坐标
final float offsetX = mScrollX - child.mLeft
final float offsetY = mScrollY - child.mTop
event.offsetLocation(offsetX, offsetY)
handled = child.dispatchTouchEvent(event)
// 恢复坐标
event.offsetLocation(-offsetX, -offsetY)
}
return handled
}
transformedEvent = MotionEvent.obtain(event)
} else {
// 多点触控
transformedEvent = event.split(newPointerIdBits)
}
// Perform any necessary transformations and dispatch.
if (child == null) {
handled = super.dispatchTouchEvent(transformedEvent)
} else {
final float offsetX = mScrollX - child.mLeft
final float offsetY = mScrollY - child.mTop
transformedEvent.offsetLocation(offsetX, offsetY)
if (! child.hasIdentityMatrix()) {
// getInverseMatrix 反平移、逆矩阵?
transformedEvent.transform(child.getInverseMatrix())
}
handled = child.dispatchTouchEvent(transformedEvent)
}
// Done.
transformedEvent.recycle()
return handled
}
```
/**
* Gets an integer where each pointer id present in the event is marked as a bit.
*/
@UnsupportedAppUsage
public final int getPointerIdBits() {
int idBits = 0
//获取所有point数量
final int pointerCount = nativeGetPointerCount(mNativePtr)
for (int i = 0
// 0000 |= 0001 -> 0001
// 0001 |= 0010 -> 0011
idBits |= 1 << nativeGetPointerId(mNativePtr, i)
}
return idBits
}
```
@UnsupportedAppUsage
public final boolean hasIdentityMatrix() {
return mRenderNode.hasIdentityMatrix();
}