ViewGroup dispatchTransformedTouchEvent 源码解析

346 阅读1分钟

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; i < pointerCount; i++) {

// 0000 |= 0001  -> 0001
// 0001 |= 0010  -> 0011

    
        idBits |= 1 << nativeGetPointerId(mNativePtr, i);
    }
    return idBits;
}
```




/**
 * Returns true if the transform matrix is the identity matrix.
 * Recomputes the matrix if necessary.
 *  如果变换矩阵是单位矩阵,
 * @return True if the transform matrix is the identity matrix, false otherwise.
 * @hide
 */
@UnsupportedAppUsage
public final boolean hasIdentityMatrix() {
    return mRenderNode.hasIdentityMatrix();
}