publicabstractclassWindow { /** Flag for the "options panel" feature. This is enabled by default. */ publicstaticfinalintFEATURE_OPTIONS_PANEL=0; /** Flag for the "no title" feature, turning off the title at the top * of the screen. */ publicstaticfinalintFEATURE_NO_TITLE=1; ... ... }
// If the event targets the accessibility focused view and this is it, start // normal event dispatch. Maybe a descendant is what will handle the click. if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) { ev.setTargetAccessibilityFocus(false); }
booleanhandled=false; if (onFilterTouchEventForSecurity(ev)) { finalintaction= ev.getAction(); finalintactionMasked= action & MotionEvent.ACTION_MASK;
// Handle an initial down. if (actionMasked == MotionEvent.ACTION_DOWN) { // Throw away all previous state when starting a new touch gesture. // The framework may have dropped the up or cancel event for the previous gesture // due to an app switch, ANR, or some other state change. cancelAndClearTouchTargets(ev); resetTouchState(); }
// Check for interception. finalboolean intercepted; if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { finalbooleandisallowIntercept= (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 intercepted, start normal event dispatch. Also if there is already // a view that is handling the gesture, do normal event dispatch. if (intercepted || mFirstTouchTarget != null) { ev.setTargetAccessibilityFocus(false); }
// Check for cancelation. finalbooleancanceled= resetCancelNextUpFlag(this) || actionMasked == MotionEvent.ACTION_CANCEL;
// Update list of touch targets for pointer down, if needed. finalbooleansplit= (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0; TouchTargetnewTouchTarget=null; booleanalreadyDispatchedToNewTouchTarget=false; if (!canceled && !intercepted) {
// If the event is targeting accessiiblity focus we give it to the // view that has accessibility focus and if it does not handle it // we clear the flag and dispatch the event to all children as usual. // We are looking up the accessibility focused host to avoid keeping // state since these events are very rare. ViewchildWithAccessibilityFocus= ev.isTargetAccessibilityFocus() ? findChildWithAccessibilityFocus() : null;
if (actionMasked == MotionEvent.ACTION_DOWN || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN) || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { finalintactionIndex= ev.getActionIndex(); // always 0 for down finalintidBitsToAssign= split ? 1 << ev.getPointerId(actionIndex) : TouchTarget.ALL_POINTER_IDS;
// Clean up earlier touch targets for this pointer id in case they // have become out of sync. removePointersFromTouchTargets(idBitsToAssign);
finalintchildrenCount= mChildrenCount; if (newTouchTarget == null && childrenCount != 0) { finalfloatx= ev.getX(actionIndex); finalfloaty= ev.getY(actionIndex); // Find a child that can receive the event. // Scan children from front to back. final ArrayList<View> preorderedList = buildTouchDispatchChildList(); finalbooleancustomOrder= preorderedList == null && isChildrenDrawingOrderEnabled(); final View[] children = mChildren; for (inti= childrenCount - 1; i >= 0; i--) { finalintchildIndex= getAndVerifyPreorderedIndex( childrenCount, i, customOrder); finalViewchild= getAndVerifyPreorderedView( preorderedList, children, childIndex);
// If there is a view that has accessibility focus we want it // to get the event first and if not handled we will perform a // normal dispatch. We may do a double iteration but this is // safer given the timeframe. if (childWithAccessibilityFocus != null) { if (childWithAccessibilityFocus != child) { continue; } childWithAccessibilityFocus = null; i = childrenCount - 1; }
if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; }
newTouchTarget = getTouchTarget(child); if (newTouchTarget != null) { // Child is already receiving touch within its bounds. // Give it the new pointer in addition to the ones it is handling. newTouchTarget.pointerIdBits |= idBitsToAssign; break; }
resetCancelNextUpFlag(child); 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 (intj=0; j < childrenCount; j++) { if (children[childIndex] == mChildren[j]) { mLastTouchDownIndex = j; break; } } } else { mLastTouchDownIndex = childIndex; } mLastTouchDownX = ev.getX(); mLastTouchDownY = ev.getY(); newTouchTarget = addTouchTarget(child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break; }
// The accessibility focus didn't handle the event, so clear // the flag and do a normal dispatch to all children. ev.setTargetAccessibilityFocus(false); } if (preorderedList != null) preorderedList.clear(); }
if (newTouchTarget == null && mFirstTouchTarget != null) { // Did not find a child to receive the event. // Assign the pointer to the least recently added target. newTouchTarget = mFirstTouchTarget; while (newTouchTarget.next != null) { newTouchTarget = newTouchTarget.next; } newTouchTarget.pointerIdBits |= idBitsToAssign; } } }
// Dispatch to touch targets. if (mFirstTouchTarget == null) { // No touch targets so treat this as an ordinary view. handled = dispatchTransformedTouchEvent(ev, canceled, null, TouchTarget.ALL_POINTER_IDS); } else { // Dispatch to touch targets, excluding the new touch target if we already // dispatched to it. Cancel touch targets if necessary. TouchTargetpredecessor=null; TouchTargettarget= mFirstTouchTarget; while (target != null) { finalTouchTargetnext= target.next; if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) { handled = true; } else { finalbooleancancelChild= 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; } }
// Update list of touch targets for pointer up or cancel, if needed. if (canceled || actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { resetTouchState(); } elseif (split && actionMasked == MotionEvent.ACTION_POINTER_UP) { finalintactionIndex= ev.getActionIndex(); finalintidBitsToRemove=1 << ev.getPointerId(actionIndex); removePointersFromTouchTargets(idBitsToRemove); } }
finalintchildrenCount= mChildrenCount; if (newTouchTarget == null && childrenCount != 0) { finalfloatx= ev.getX(actionIndex); finalfloaty= ev.getY(actionIndex); // Find a child that can receive the event. // Scan children from front to back. final ArrayList<View> preorderedList = buildTouchDispatchChildList(); finalbooleancustomOrder= preorderedList == null && isChildrenDrawingOrderEnabled(); final View[] children = mChildren; for (inti= childrenCount - 1; i >= 0; i--) { finalintchildIndex= getAndVerifyPreorderedIndex( childrenCount, i, customOrder); finalViewchild= getAndVerifyPreorderedView( preorderedList, children, childIndex);
// 如果有一个具有可访问性焦点的视图,我们希望它首先获得事件,如果不处理,我们将执行正常的分派。我们可以进行两次迭代,但是考虑到时间范围,这样做更安全。 if (childWithAccessibilityFocus != null) { if (childWithAccessibilityFocus != child) { continue; } childWithAccessibilityFocus = null; i = childrenCount - 1; }
if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; }
newTouchTarget = getTouchTarget(child); if (newTouchTarget != null) { // Child is already receiving touch within its bounds. // Give it the new pointer in addition to the ones it is handling. newTouchTarget.pointerIdBits |= idBitsToAssign; break; }
resetCancelNextUpFlag(child); 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 (intj=0; j < childrenCount; j++) { if (children[childIndex] == mChildren[j]) { mLastTouchDownIndex = j; break; } } } else { mLastTouchDownIndex = childIndex; } mLastTouchDownX = ev.getX(); mLastTouchDownY = ev.getY(); newTouchTarget = addTouchTarget(child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break; }
// The accessibility focus didn't handle the event, so clear // the flag and do a normal dispatch to all children. ev.setTargetAccessibilityFocus(false); } if (preorderedList != null) preorderedList.clear(); }