ViewGroup dispatchTouchEvent方法中 mFirstTouchTarget标志是否为空的含义

本文深入探讨了ViewGroup中dispatchTouchEvent方法的实现细节,重点分析了mFirstTouchTarget变量的作用。当ACTION_DOWN事件发生时,若未找到消费Touch事件的view,mFirstTouchTarget将保持空状态;一旦找到消费view,即标记mFirstTouchTarget,后续ACTION_UP或ACTION_CANCEL事件即可由该view处理。mFirstTouchTarget为TouchTarget实例,用于多点触控监测。

    在ViewGroup dispatchTouchEvent方法中首次出现mFirstTouchTarget的语句为:

     if (actionMasked == MotionEvent.ACTION_DOWN|| mFirstTouchTarget !=null)

   如果是ACTION_DOWN事件,表示还没有找到消费Touch事件的view,如果找到了,会标记mFirstTouchTarget,此时mFirstTouchTarget不为空,后面的ACTION_UP、ACTION_CANCEL事件就有了消费的view。

    备注:mFirstTouchTarget是TouchTarget类的对象,TouchTarget类封装了被触摸的View以及本次触摸的ID,主要用于多点触控监测。

转载于:https://www.cnblogs.com/acesui/p/10130590.html

public boolean dispatchTouchEvent(MotionEvent ev) { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(ev, 1); } if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) { ev.setTargetAccessibilityFocus(false); } boolean handled = false; if (onFilterTouchEventForSecurity(ev)) { final int action = ev.getAction(); final int actionMasked = action & MotionEvent.ACTION_MASK; if (actionMasked == MotionEvent.ACTION_DOWN) { cancelAndClearTouchTargets(ev); resetTouchState(); } final boolean intercepted; ViewRootImpl viewRootImpl = getViewRootImpl(); if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; final boolean isBackGestureInProgress = (viewRootImpl != null && viewRootImpl.getOnBackInvokedDispatcher().isBackGestureInProgress()); if (!disallowIntercept || isBackGestureInProgress) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); // restore action in case it was changed } else { intercepted = false; } } else { intercepted = true; } if (intercepted || mFirstTouchTarget != null) { ev.setTargetAccessibilityFocus(false); } final boolean canceled = resetCancelNextUpFlag(this) || actionMasked == MotionEvent.ACTION_CANCEL; final boolean isMouseEvent = ev.getSource() == InputDevice.SOURCE_MOUSE; final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0 && !isMouseEvent; TouchTarget newTouchTarget = null; boolean alreadyDispatchedToNewTouchTarget = false; if (!canceled && !intercepted) { View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus() ? findChildWithAccessibilityFocus() : null; if (actionMasked == MotionEvent.ACTION_DOWN || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN) || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { final int actionIndex = ev.getActionIndex(); // always 0 for down final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex) : TouchTarget.ALL_POINTER_IDS; removePointersFromTouchTargets(idBitsToAssign); final int childrenCount = mChildrenCount; if (newTouchTarget == null && childrenCount != 0) { final float x = ev.getXDispatchLocation(actionIndex); final float y = ev.getYDispatchLocation(actionIndex); final ArrayList preorderedList = buildTouchDispatchChildList(); final boolean customOrder = preorderedList == null && isChildrenDrawingOrderEnabled(); final View[] children = mChildren; for (int i = childrenCount - 1; i >= 0; i–) { final int childIndex = getAndVerifyPreorderedIndex( childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView( preorderedList, children, childIndex); if (childWithAccessibilityFocus != null) { if (childWithAccessibilityFocus != child) { continue; } childWithAccessibilityFocus = null; i = childrenCount; } if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; } newTouchTarget = getTouchTarget(child); if (newTouchTarget != null) { newTouchTarget.pointerIdBits |= idBitsToAssign; break; } resetCancelNextUpFlag(child); if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { . mLastTouchDownTime = ev.getDownTime(); if (preorderedList != null) { for (int j = 0; j < childrenCount; j++) { if (children[childIndex] == mChildren[j]) { mLastTouchDownIndex = j; break; } } } else { mLastTouchDownIndex = childIndex; } mLastTouchDownX = x; mLastTouchDownY = y; newTouchTarget = addTouchTarget(child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break; } ev.setTargetAccessibilityFocus(false); } if (preorderedList != null) preorderedList.clear(); } if (newTouchTarget == null && mFirstTouchTarget != null) { newTouchTarget = mFirstTouchTarget; while (newTouchTarget.next != null) { newTouchTarget = newTouchTarget.next; } newTouchTarget.pointerIdBits |= idBitsToAssign; } } } if (mFirstTouchTarget == null) { // No touch targets so treat this as an ordinary view. handled = dispatchTransformedTouchEvent(ev, canceled, null, TouchTarget.ALL_POINTER_IDS); } else { TouchTarget predecessor = null; TouchTarget target = mFirstTouchTarget; while (target != null) { final TouchTarget next = target.next; if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) { handled = true; } else { final boolean cancelChild = resetCancelNextUpFlag(target.child) || intercepted; if (dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits)) { handled = true; } if (cancelChild) { if (predecessor == null) { mFirstTouchTarget = next; } else { predecessor.next = next; } target.recycle(); target = next; continue; } } predecessor = target; target = next; } } if (canceled || actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { resetTouchState(); } else if (split && actionMasked == MotionEvent.ACTION_POINTER_UP) { final int actionIndex = ev.getActionIndex(); final int idBitsToRemove = 1 << ev.getPointerId(actionIndex); removePointersFromTouchTargets(idBitsToRemove); } } if (!handled && mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1); } return handled; }逐行深度解析这个方法
最新发布
09-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值