Android Touch事件分发深入了解

2019-12-10 18:29:26丽君

    接下来,会进入第三阶段的工作:

final boolean canceled = resetCancelNextUpFlag(this) || actionMasked == MotionEvent.ACTION_CANCEL;
final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
TouchTarget newTouchTarget = null;
boolean alreadyDispatchedToNewTouchTarget = false;
if (!canceled && !intercepted) {
  // 不是ACTION_CANCEL并且不拦截
  if (actionMasked == MotionEvent.ACTION_DOWN) {
     // 若当前事件为ACTION_DOWN则去寻找这次事件新出现的touch target
     final int actionIndex = ev.getActionIndex(); // always 0 for down

     ...

     final int childrenCount = mChildrenCount;
     if (newTouchTarget == null && childrenCount != 0) {
       // 根据触摸的坐标寻找能够接收这个事件的touch target
       final float x = ev.getX(actionIndex);
       final float y = ev.getY(actionIndex);

       final View[] children = mChildren;
       // 遍历所有子View
       for (int i = childrenCount - 1; i >= 0; i--) {
         final int childIndex = i;
         final View child = children[childIndex];
         // 寻找可接收这个事件并且touch事件坐标在其区域内的子View
         if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) {
           continue;
         }

         newTouchTarget = getTouchTarget(child); // 找到了符合条件的子View,赋值给newTouchTarget
         if (newTouchTarget != null) {
           //Child is already receiving touch within its bounds.
           //Give it the new pointer in addition to ones it is handling.
           newTouchTarget.pointerIdBits |= idBitsToAssign;
           break;
         }
         resetCancelNextUpFlag(child);
         // 把ACTION_DOWN事件传递给子组件进行处理
         if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
           //Child wants to receive touch within its bounds.
           mLastTouchDownTime = ev.getDownTime();
           if (preorderedList != null) {
             //childIndex points into presorted list, find original index
             for (int j=0;j<childrenCount;j++) {
               if (children[childIndex]==mChildren[j]) {
                 mLastTouchDownIndex=j;
                 break;
               }
             }
           } else {
             mLastTouchDownIndex = childIndex;
           }
           mLastTouchDownX = ev.getX();
           mLastTouchDownY = ev.getY();
           //把mFirstTouchTarget赋值为newTouchTarget,此子View成为新的touch事件的起点
           newTouchTarget = addTouchTarget(child, idBitsToAssign);
           alreadyDispatchedToNewTouchTarget = true;
           break;
         }           
       }
     }
  }
}