Loading core/java/android/view/View.java +19 −103 Original line number Original line Diff line number Diff line Loading @@ -4163,11 +4163,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ */ private static boolean sUseDefaultFocusHighlight; private static boolean sUseDefaultFocusHighlight; /** * True if zero-sized views can be focused. */ private static boolean sCanFocusZeroSized; private String mTransitionName; private String mTransitionName; static class TintInfo { static class TintInfo { Loading Loading @@ -4748,8 +4743,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, sUseDefaultFocusHighlight = context.getResources().getBoolean( sUseDefaultFocusHighlight = context.getResources().getBoolean( com.android.internal.R.bool.config_useDefaultFocusHighlight); com.android.internal.R.bool.config_useDefaultFocusHighlight); sCanFocusZeroSized = targetSdkVersion < Build.VERSION_CODES.P; sCompatibilityDone = true; sCompatibilityDone = true; } } } } Loading Loading @@ -6957,7 +6950,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, void clearFocusInternal(View focused, boolean propagate, boolean refocus) { void clearFocusInternal(View focused, boolean propagate, boolean refocus) { if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { mPrivateFlags &= ~PFLAG_FOCUSED; mPrivateFlags &= ~PFLAG_FOCUSED; clearParentsWantFocus(); if (propagate && mParent != null) { if (propagate && mParent != null) { mParent.clearChildFocus(this); mParent.clearChildFocus(this); Loading Loading @@ -10939,9 +10931,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * descendants. * descendants. * * * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns * false), or if it can't be focused due to other conditions (not focusable in touch mode * false), or if it is focusable and it is not focusable in touch mode * ({@link #isFocusableInTouchMode}) while the device is in touch mode, not visible, not * ({@link #isFocusableInTouchMode}) while the device is in touch mode. * enabled, or has no size). * * * See also {@link #focusSearch(int)}, which is what you call to say that you * See also {@link #focusSearch(int)}, which is what you call to say that you * have focus, and you want your parent to look for the next one. * have focus, and you want your parent to look for the next one. Loading Loading @@ -10979,17 +10970,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ */ @TestApi @TestApi public boolean restoreFocusNotInCluster() { public boolean restoreFocusNotInCluster() { return requestFocus(); return requestFocus(View.FOCUS_DOWN); } } /** /** * Gives focus to the default-focus view in the view hierarchy that has this view as a root. * Gives focus to the default-focus view in the view hierarchy that has this view as a root. * If the default-focus view cannot be found, falls back to calling {@link #requestFocus()}. * If the default-focus view cannot be found, falls back to calling {@link #requestFocus(int)}. * * * @return Whether this view or one of its descendants actually took focus * @return Whether this view or one of its descendants actually took focus */ */ public boolean restoreDefaultFocus() { public boolean restoreDefaultFocus() { return requestFocus(); return requestFocus(View.FOCUS_DOWN); } } /** /** Loading Loading @@ -11048,7 +11039,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) { private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) { // need to be focusable // need to be focusable if (!canTakeFocus()) { if ((mViewFlags & FOCUSABLE) != FOCUSABLE || (mViewFlags & VISIBILITY_MASK) != VISIBLE || (mViewFlags & ENABLED_MASK) != ENABLED) { return false; return false; } } Loading @@ -11063,21 +11056,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return false; return false; } } if (!isLaidOut()) { mPrivateFlags |= PFLAG_WANTS_FOCUS; } handleFocusGainInternal(direction, previouslyFocusedRect); handleFocusGainInternal(direction, previouslyFocusedRect); return true; return true; } } void clearParentsWantFocus() { if (mParent instanceof View) { ((View) mParent).mPrivateFlags &= ~PFLAG_WANTS_FOCUS; ((View) mParent).clearParentsWantFocus(); } } /** /** * Call this to try to give focus to a specific view or to one of its descendants. This is a * Call this to try to give focus to a specific view or to one of its descendants. This is a * special variant of {@link #requestFocus() } that will allow views that are not focusable in * special variant of {@link #requestFocus() } that will allow views that are not focusable in Loading Loading @@ -13449,13 +13431,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo.mUnbufferedDispatchRequested = true; mAttachInfo.mUnbufferedDispatchRequested = true; } } private boolean canTakeFocus() { return ((mViewFlags & VISIBILITY_MASK) == VISIBLE) && ((mViewFlags & FOCUSABLE) == FOCUSABLE) && ((mViewFlags & ENABLED_MASK) == ENABLED) && (sCanFocusZeroSized || !isLaidOut() || (mBottom > mTop) && (mRight > mLeft)); } /** /** * Set flags controlling behavior of this view. * Set flags controlling behavior of this view. * * Loading @@ -13475,7 +13450,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; return; } } int privateFlags = mPrivateFlags; int privateFlags = mPrivateFlags; boolean shouldNotifyFocusableAvailable = false; // If focusable is auto, update the FOCUSABLE bit. // If focusable is auto, update the FOCUSABLE bit. int focusableChangedByAuto = 0; int focusableChangedByAuto = 0; Loading Loading @@ -13514,7 +13488,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, || focusableChangedByAuto == 0 || focusableChangedByAuto == 0 || viewRootImpl == null || viewRootImpl == null || viewRootImpl.mThread == Thread.currentThread()) { || viewRootImpl.mThread == Thread.currentThread()) { shouldNotifyFocusableAvailable = true; mParent.focusableViewAvailable(this); } } } } } } Loading @@ -13537,7 +13511,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // about in case nothing has focus. even if this specific view // about in case nothing has focus. even if this specific view // isn't focusable, it may contain something that is, so let // isn't focusable, it may contain something that is, so let // the root view try to give this focus if nothing else does. // the root view try to give this focus if nothing else does. shouldNotifyFocusableAvailable = true; if ((mParent != null) && ((mViewFlags & ENABLED_MASK) == ENABLED) && (mBottom > mTop) && (mRight > mLeft)) { mParent.focusableViewAvailable(this); } } } } } Loading @@ -13546,15 +13523,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // a view becoming enabled should notify the parent as long as the view is also // a view becoming enabled should notify the parent as long as the view is also // visible and the parent wasn't already notified by becoming visible during this // visible and the parent wasn't already notified by becoming visible during this // setFlags invocation. // setFlags invocation. shouldNotifyFocusableAvailable = true; if ((mViewFlags & VISIBILITY_MASK) == VISIBLE } else { && ((changed & VISIBILITY_MASK) == 0)) { if (hasFocus()) clearFocus(); if ((mParent != null) && (mViewFlags & ENABLED_MASK) == ENABLED) { mParent.focusableViewAvailable(this); } } } } } else { if (shouldNotifyFocusableAvailable) { if (hasFocus()) clearFocus(); if (mParent != null && canTakeFocus()) { mParent.focusableViewAvailable(this); } } } } Loading Loading @@ -20047,58 +20023,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } } final boolean wasLaidOut = isLaidOut(); mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; mPrivateFlags3 |= PFLAG3_IS_LAID_OUT; mPrivateFlags3 |= PFLAG3_IS_LAID_OUT; if (!wasLaidOut && isFocused()) { mPrivateFlags &= ~PFLAG_WANTS_FOCUS; if (canTakeFocus()) { // We have a robust focus, so parents should no longer be wanting focus. clearParentsWantFocus(); } else if (!getViewRootImpl().isInLayout()) { // This is a weird case. Most-likely the user, rather than ViewRootImpl, called // layout. In this case, there's no guarantee that parent layouts will be evaluated // and thus the safest action is to clear focus here. clearFocusInternal(null, /* propagate */ true, /* refocus */ false); clearParentsWantFocus(); } else if (!hasParentWantsFocus()) { // original requestFocus was likely on this view directly, so just clear focus clearFocusInternal(null, /* propagate */ true, /* refocus */ false); } // otherwise, we let parents handle re-assigning focus during their layout passes. } else if ((mPrivateFlags & PFLAG_WANTS_FOCUS) != 0) { mPrivateFlags &= ~PFLAG_WANTS_FOCUS; View focused = findFocus(); if (focused != null) { // Try to restore focus as close as possible to our starting focus. if (!restoreDefaultFocus() && !hasParentWantsFocus()) { // Give up and clear focus once we've reached the top-most parent which wants // focus. focused.clearFocusInternal(null, /* propagate */ true, /* refocus */ false); } } } if ((mPrivateFlags3 & PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT) != 0) { if ((mPrivateFlags3 & PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT) != 0) { mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; notifyEnterOrExitForAutoFillIfNeeded(true); notifyEnterOrExitForAutoFillIfNeeded(true); } } } } private boolean hasParentWantsFocus() { ViewParent parent = mParent; while (parent instanceof ViewGroup) { ViewGroup pv = (ViewGroup) parent; if ((pv.mPrivateFlags & PFLAG_WANTS_FOCUS) != 0) { return true; } parent = pv.mParent; } return false; } /** /** * Called from layout when this view should * Called from layout when this view should * assign a size and position to each of its children. * assign a size and position to each of its children. Loading Loading @@ -20205,23 +20138,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mOverlay.getOverlayView().setRight(newWidth); mOverlay.getOverlayView().setRight(newWidth); mOverlay.getOverlayView().setBottom(newHeight); mOverlay.getOverlayView().setBottom(newHeight); } } // If this isn't laid out yet, focus assignment will be handled during the "deferment/ // backtracking" of requestFocus during layout, so don't touch focus here. if (!sCanFocusZeroSized && isLaidOut()) { if (newWidth <= 0 || newHeight <= 0) { if (hasFocus()) { clearFocus(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).clearFocusedInCluster(); } } clearAccessibilityFocus(); } else if (oldWidth <= 0 || oldHeight <= 0) { if (mParent != null && canTakeFocus()) { mParent.focusableViewAvailable(this); } } } rebuildOutline(); rebuildOutline(); } } core/java/android/view/ViewGroup.java +3 −12 Original line number Original line Diff line number Diff line Loading @@ -3215,31 +3215,22 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } int descendantFocusability = getDescendantFocusability(); int descendantFocusability = getDescendantFocusability(); boolean result; switch (descendantFocusability) { switch (descendantFocusability) { case FOCUS_BLOCK_DESCENDANTS: case FOCUS_BLOCK_DESCENDANTS: result = super.requestFocus(direction, previouslyFocusedRect); return super.requestFocus(direction, previouslyFocusedRect); break; case FOCUS_BEFORE_DESCENDANTS: { case FOCUS_BEFORE_DESCENDANTS: { final boolean took = super.requestFocus(direction, previouslyFocusedRect); final boolean took = super.requestFocus(direction, previouslyFocusedRect); result = took ? took : onRequestFocusInDescendants(direction, return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect); previouslyFocusedRect); break; } } case FOCUS_AFTER_DESCENDANTS: { case FOCUS_AFTER_DESCENDANTS: { final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect); final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect); result = took ? took : super.requestFocus(direction, previouslyFocusedRect); return took ? took : super.requestFocus(direction, previouslyFocusedRect); break; } } default: default: throw new IllegalStateException("descendant focusability must be " throw new IllegalStateException("descendant focusability must be " + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS " + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS " + "but is " + descendantFocusability); + "but is " + descendantFocusability); } } if (result && !isLaidOut() && ((mPrivateFlags & PFLAG_WANTS_FOCUS) == 0)) { mPrivateFlags |= PFLAG_WANTS_FOCUS; } return result; } } /** /** Loading Loading
core/java/android/view/View.java +19 −103 Original line number Original line Diff line number Diff line Loading @@ -4163,11 +4163,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ */ private static boolean sUseDefaultFocusHighlight; private static boolean sUseDefaultFocusHighlight; /** * True if zero-sized views can be focused. */ private static boolean sCanFocusZeroSized; private String mTransitionName; private String mTransitionName; static class TintInfo { static class TintInfo { Loading Loading @@ -4748,8 +4743,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, sUseDefaultFocusHighlight = context.getResources().getBoolean( sUseDefaultFocusHighlight = context.getResources().getBoolean( com.android.internal.R.bool.config_useDefaultFocusHighlight); com.android.internal.R.bool.config_useDefaultFocusHighlight); sCanFocusZeroSized = targetSdkVersion < Build.VERSION_CODES.P; sCompatibilityDone = true; sCompatibilityDone = true; } } } } Loading Loading @@ -6957,7 +6950,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, void clearFocusInternal(View focused, boolean propagate, boolean refocus) { void clearFocusInternal(View focused, boolean propagate, boolean refocus) { if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { if ((mPrivateFlags & PFLAG_FOCUSED) != 0) { mPrivateFlags &= ~PFLAG_FOCUSED; mPrivateFlags &= ~PFLAG_FOCUSED; clearParentsWantFocus(); if (propagate && mParent != null) { if (propagate && mParent != null) { mParent.clearChildFocus(this); mParent.clearChildFocus(this); Loading Loading @@ -10939,9 +10931,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * descendants. * descendants. * * * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns * A view will not actually take focus if it is not focusable ({@link #isFocusable} returns * false), or if it can't be focused due to other conditions (not focusable in touch mode * false), or if it is focusable and it is not focusable in touch mode * ({@link #isFocusableInTouchMode}) while the device is in touch mode, not visible, not * ({@link #isFocusableInTouchMode}) while the device is in touch mode. * enabled, or has no size). * * * See also {@link #focusSearch(int)}, which is what you call to say that you * See also {@link #focusSearch(int)}, which is what you call to say that you * have focus, and you want your parent to look for the next one. * have focus, and you want your parent to look for the next one. Loading Loading @@ -10979,17 +10970,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ */ @TestApi @TestApi public boolean restoreFocusNotInCluster() { public boolean restoreFocusNotInCluster() { return requestFocus(); return requestFocus(View.FOCUS_DOWN); } } /** /** * Gives focus to the default-focus view in the view hierarchy that has this view as a root. * Gives focus to the default-focus view in the view hierarchy that has this view as a root. * If the default-focus view cannot be found, falls back to calling {@link #requestFocus()}. * If the default-focus view cannot be found, falls back to calling {@link #requestFocus(int)}. * * * @return Whether this view or one of its descendants actually took focus * @return Whether this view or one of its descendants actually took focus */ */ public boolean restoreDefaultFocus() { public boolean restoreDefaultFocus() { return requestFocus(); return requestFocus(View.FOCUS_DOWN); } } /** /** Loading Loading @@ -11048,7 +11039,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) { private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) { // need to be focusable // need to be focusable if (!canTakeFocus()) { if ((mViewFlags & FOCUSABLE) != FOCUSABLE || (mViewFlags & VISIBILITY_MASK) != VISIBLE || (mViewFlags & ENABLED_MASK) != ENABLED) { return false; return false; } } Loading @@ -11063,21 +11056,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return false; return false; } } if (!isLaidOut()) { mPrivateFlags |= PFLAG_WANTS_FOCUS; } handleFocusGainInternal(direction, previouslyFocusedRect); handleFocusGainInternal(direction, previouslyFocusedRect); return true; return true; } } void clearParentsWantFocus() { if (mParent instanceof View) { ((View) mParent).mPrivateFlags &= ~PFLAG_WANTS_FOCUS; ((View) mParent).clearParentsWantFocus(); } } /** /** * Call this to try to give focus to a specific view or to one of its descendants. This is a * Call this to try to give focus to a specific view or to one of its descendants. This is a * special variant of {@link #requestFocus() } that will allow views that are not focusable in * special variant of {@link #requestFocus() } that will allow views that are not focusable in Loading Loading @@ -13449,13 +13431,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo.mUnbufferedDispatchRequested = true; mAttachInfo.mUnbufferedDispatchRequested = true; } } private boolean canTakeFocus() { return ((mViewFlags & VISIBILITY_MASK) == VISIBLE) && ((mViewFlags & FOCUSABLE) == FOCUSABLE) && ((mViewFlags & ENABLED_MASK) == ENABLED) && (sCanFocusZeroSized || !isLaidOut() || (mBottom > mTop) && (mRight > mLeft)); } /** /** * Set flags controlling behavior of this view. * Set flags controlling behavior of this view. * * Loading @@ -13475,7 +13450,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; return; } } int privateFlags = mPrivateFlags; int privateFlags = mPrivateFlags; boolean shouldNotifyFocusableAvailable = false; // If focusable is auto, update the FOCUSABLE bit. // If focusable is auto, update the FOCUSABLE bit. int focusableChangedByAuto = 0; int focusableChangedByAuto = 0; Loading Loading @@ -13514,7 +13488,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, || focusableChangedByAuto == 0 || focusableChangedByAuto == 0 || viewRootImpl == null || viewRootImpl == null || viewRootImpl.mThread == Thread.currentThread()) { || viewRootImpl.mThread == Thread.currentThread()) { shouldNotifyFocusableAvailable = true; mParent.focusableViewAvailable(this); } } } } } } Loading @@ -13537,7 +13511,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // about in case nothing has focus. even if this specific view // about in case nothing has focus. even if this specific view // isn't focusable, it may contain something that is, so let // isn't focusable, it may contain something that is, so let // the root view try to give this focus if nothing else does. // the root view try to give this focus if nothing else does. shouldNotifyFocusableAvailable = true; if ((mParent != null) && ((mViewFlags & ENABLED_MASK) == ENABLED) && (mBottom > mTop) && (mRight > mLeft)) { mParent.focusableViewAvailable(this); } } } } } Loading @@ -13546,15 +13523,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // a view becoming enabled should notify the parent as long as the view is also // a view becoming enabled should notify the parent as long as the view is also // visible and the parent wasn't already notified by becoming visible during this // visible and the parent wasn't already notified by becoming visible during this // setFlags invocation. // setFlags invocation. shouldNotifyFocusableAvailable = true; if ((mViewFlags & VISIBILITY_MASK) == VISIBLE } else { && ((changed & VISIBILITY_MASK) == 0)) { if (hasFocus()) clearFocus(); if ((mParent != null) && (mViewFlags & ENABLED_MASK) == ENABLED) { mParent.focusableViewAvailable(this); } } } } } else { if (shouldNotifyFocusableAvailable) { if (hasFocus()) clearFocus(); if (mParent != null && canTakeFocus()) { mParent.focusableViewAvailable(this); } } } } Loading Loading @@ -20047,58 +20023,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } } final boolean wasLaidOut = isLaidOut(); mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; mPrivateFlags &= ~PFLAG_FORCE_LAYOUT; mPrivateFlags3 |= PFLAG3_IS_LAID_OUT; mPrivateFlags3 |= PFLAG3_IS_LAID_OUT; if (!wasLaidOut && isFocused()) { mPrivateFlags &= ~PFLAG_WANTS_FOCUS; if (canTakeFocus()) { // We have a robust focus, so parents should no longer be wanting focus. clearParentsWantFocus(); } else if (!getViewRootImpl().isInLayout()) { // This is a weird case. Most-likely the user, rather than ViewRootImpl, called // layout. In this case, there's no guarantee that parent layouts will be evaluated // and thus the safest action is to clear focus here. clearFocusInternal(null, /* propagate */ true, /* refocus */ false); clearParentsWantFocus(); } else if (!hasParentWantsFocus()) { // original requestFocus was likely on this view directly, so just clear focus clearFocusInternal(null, /* propagate */ true, /* refocus */ false); } // otherwise, we let parents handle re-assigning focus during their layout passes. } else if ((mPrivateFlags & PFLAG_WANTS_FOCUS) != 0) { mPrivateFlags &= ~PFLAG_WANTS_FOCUS; View focused = findFocus(); if (focused != null) { // Try to restore focus as close as possible to our starting focus. if (!restoreDefaultFocus() && !hasParentWantsFocus()) { // Give up and clear focus once we've reached the top-most parent which wants // focus. focused.clearFocusInternal(null, /* propagate */ true, /* refocus */ false); } } } if ((mPrivateFlags3 & PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT) != 0) { if ((mPrivateFlags3 & PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT) != 0) { mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; notifyEnterOrExitForAutoFillIfNeeded(true); notifyEnterOrExitForAutoFillIfNeeded(true); } } } } private boolean hasParentWantsFocus() { ViewParent parent = mParent; while (parent instanceof ViewGroup) { ViewGroup pv = (ViewGroup) parent; if ((pv.mPrivateFlags & PFLAG_WANTS_FOCUS) != 0) { return true; } parent = pv.mParent; } return false; } /** /** * Called from layout when this view should * Called from layout when this view should * assign a size and position to each of its children. * assign a size and position to each of its children. Loading Loading @@ -20205,23 +20138,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mOverlay.getOverlayView().setRight(newWidth); mOverlay.getOverlayView().setRight(newWidth); mOverlay.getOverlayView().setBottom(newHeight); mOverlay.getOverlayView().setBottom(newHeight); } } // If this isn't laid out yet, focus assignment will be handled during the "deferment/ // backtracking" of requestFocus during layout, so don't touch focus here. if (!sCanFocusZeroSized && isLaidOut()) { if (newWidth <= 0 || newHeight <= 0) { if (hasFocus()) { clearFocus(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).clearFocusedInCluster(); } } clearAccessibilityFocus(); } else if (oldWidth <= 0 || oldHeight <= 0) { if (mParent != null && canTakeFocus()) { mParent.focusableViewAvailable(this); } } } rebuildOutline(); rebuildOutline(); } }
core/java/android/view/ViewGroup.java +3 −12 Original line number Original line Diff line number Diff line Loading @@ -3215,31 +3215,22 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } int descendantFocusability = getDescendantFocusability(); int descendantFocusability = getDescendantFocusability(); boolean result; switch (descendantFocusability) { switch (descendantFocusability) { case FOCUS_BLOCK_DESCENDANTS: case FOCUS_BLOCK_DESCENDANTS: result = super.requestFocus(direction, previouslyFocusedRect); return super.requestFocus(direction, previouslyFocusedRect); break; case FOCUS_BEFORE_DESCENDANTS: { case FOCUS_BEFORE_DESCENDANTS: { final boolean took = super.requestFocus(direction, previouslyFocusedRect); final boolean took = super.requestFocus(direction, previouslyFocusedRect); result = took ? took : onRequestFocusInDescendants(direction, return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect); previouslyFocusedRect); break; } } case FOCUS_AFTER_DESCENDANTS: { case FOCUS_AFTER_DESCENDANTS: { final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect); final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect); result = took ? took : super.requestFocus(direction, previouslyFocusedRect); return took ? took : super.requestFocus(direction, previouslyFocusedRect); break; } } default: default: throw new IllegalStateException("descendant focusability must be " throw new IllegalStateException("descendant focusability must be " + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS " + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS " + "but is " + descendantFocusability); + "but is " + descendantFocusability); } } if (result && !isLaidOut() && ((mPrivateFlags & PFLAG_WANTS_FOCUS) == 0)) { mPrivateFlags |= PFLAG_WANTS_FOCUS; } return result; } } /** /** Loading