dispatchTouchEvent源码分析

本文深入探讨了Android中dispatchTouchEvent方法处理DOWN、MOVE和UP事件的过程。在DOWN事件中,主要任务是确定事件的消费路径,通过遍历子View并转换坐标系来传递事件。如果子View消费了事件,则设置mFirstTouchTarget属性,形成事件消费链。对于MOVE和UP事件的分析未在摘要中详细展开。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dispatchTouchEvent 方法可以根据DOWN事件和move,up事件分别分析。本文章不考虑多触摸点,TouchTarget链是储存了多触摸点,pointerIdBits 属性表示触摸点Id

1.DOWN事件,主要作用是确定消费路线(把处理事件的View赋值给mFirstTouchTarget)

dispatchTouchEvent方法的简要代码

final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
        || mFirstTouchTarget != null) {
    final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
    if (!disallowIntercept) {
        intercepted = onInterceptTouchEvent(ev);
        ev.setAction(action); // restore action in case it was changed
    } else {
        intercepted = false;
    }
} else {
    // There are no touch targets and this action is not an initial down
    // so this view group continues to intercept touches.
    intercepted = true;
}
if (!canceled && !intercepted){

     //Down事件  
      if (actionMasked == MotionEvent.ACTION_DOWN
        || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
        || actionMasked == MotionEvent.ACTION_HOVER_MOVE){
          if(子view消费事件){
             mFirstTouchTarget=子view;
          }
      
       }

}

// move,up事件
if (mFirstTouchTarget == null) {
    // No touch targets so treat this as an ordinary view.
    handled = dispatchTransformedTouchEvent(ev, canceled, null,
            TouchTarget.ALL_POINTER_IDS);
} else {

    dispatchTransformedTouchEvent(ev, cancelChild,
        target.child, target.pointerIdBits)

}

 

具体过程:遍历子view ,判断触摸点是否在该view中,不在,跳过该view

if (!canViewReceivePointerEvents(child)
        || !isTransformedTouchPointInView(x, y, child, null)) {
    ev.setTargetAccessibilityFocus(false);
    continue;
}

触摸点在该view的范围中,调用dispatchTransformedTouchEvent, 把坐标系转换为子view 坐标系,事件传递给子view,子view执行onTouchEvent 返回值

// 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()) {
        transformedEvent.transform(child.getInverseMatrix());
    }

    handled = child.dispatchTouchEvent(transformedEvent);
}

当返回值为true时,表示子view消费了这个点击事件,把该View赋值给mFirstTouchTarget,表示ViewGroup中有子View消费了这个点击事件。

mFirstTouchTarget = target;

alreadyDispatchedToNewTouchTarget = true;

结论:在View树中每个ViewGroup的mFirstTouchTarget属性指向下个消费了事件的子view,形成一个消费链。这是Down事件的主要功能。

2.move,up事件

遍历完子view后,mFirstTouchTarget为空直接调用自身的onTouchEvent方法,不为空表示有子view消费事件,事件向下传递。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值