Loading api/current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -584,6 +584,7 @@ package android { field public static final int flipInterval = 16843129; // 0x1010179 field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedByDefault = 16844101; // 0x1010545 field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac Loading Loading @@ -43512,6 +43513,7 @@ package android.view { method public final boolean isFocusable(); method public final boolean isFocusableInTouchMode(); method public boolean isFocused(); method public final boolean isFocusedByDefault(); method public boolean isHapticFeedbackEnabled(); method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); Loading Loading @@ -43642,8 +43644,8 @@ package android.view { method public final void requestUnbufferedDispatch(android.view.MotionEvent); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(int); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public boolean restoreLastFocus(); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); method public void scrollBy(int, int); Loading Loading @@ -43681,6 +43683,7 @@ package android.view { method public void setFitsSystemWindows(boolean); method public void setFocusable(boolean); method public void setFocusableInTouchMode(boolean); method public void setFocusedByDefault(boolean); method public void setForeground(android.graphics.drawable.Drawable); method public void setForegroundGravity(int); method public void setForegroundTintList(android.content.res.ColorStateList); api/system-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ package android { field public static final int flipInterval = 16843129; // 0x1010179 field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedByDefault = 16844101; // 0x1010545 field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac Loading Loading @@ -46736,6 +46737,7 @@ package android.view { method public final boolean isFocusable(); method public final boolean isFocusableInTouchMode(); method public boolean isFocused(); method public final boolean isFocusedByDefault(); method public boolean isHapticFeedbackEnabled(); method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); Loading Loading @@ -46866,8 +46868,8 @@ package android.view { method public final void requestUnbufferedDispatch(android.view.MotionEvent); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(int); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public boolean restoreLastFocus(); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); method public void scrollBy(int, int); Loading Loading @@ -46905,6 +46907,7 @@ package android.view { method public void setFitsSystemWindows(boolean); method public void setFocusable(boolean); method public void setFocusableInTouchMode(boolean); method public void setFocusedByDefault(boolean); method public void setForeground(android.graphics.drawable.Drawable); method public void setForegroundGravity(int); method public void setForegroundTintList(android.content.res.ColorStateList); api/test-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -584,6 +584,7 @@ package android { field public static final int flipInterval = 16843129; // 0x1010179 field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedByDefault = 16844101; // 0x1010545 field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac Loading Loading @@ -43802,6 +43803,7 @@ package android.view { method public final boolean isFocusable(); method public final boolean isFocusableInTouchMode(); method public boolean isFocused(); method public final boolean isFocusedByDefault(); method public boolean isHapticFeedbackEnabled(); method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); Loading Loading @@ -43932,8 +43934,8 @@ package android.view { method public final void requestUnbufferedDispatch(android.view.MotionEvent); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(int); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public boolean restoreLastFocus(); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); method public void scrollBy(int, int); Loading Loading @@ -43971,6 +43973,7 @@ package android.view { method public void setFitsSystemWindows(boolean); method public void setFocusable(boolean); method public void setFocusableInTouchMode(boolean); method public void setFocusedByDefault(boolean); method public void setForeground(android.graphics.drawable.Drawable); method public void setForegroundGravity(int); method public void setForegroundTintList(android.content.res.ColorStateList); core/java/android/view/View.java +84 −10 Original line number Diff line number Diff line Loading @@ -2502,7 +2502,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG3_CLUSTER * 1 PFLAG3_SECTION * 1 PFLAG3_FINGER_DOWN * xxxxx * NO LONGER NEEDED, SHOULD BE REUSED * * 1 PFLAG3_FOCUSED_BY_DEFAULT * xxxx * NO LONGER NEEDED, SHOULD BE REUSED * * 1 PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE * 1 PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED * 1 PFLAG3_TEMPORARY_DETACH Loading Loading @@ -2722,6 +2723,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static final int PFLAG3_FINGER_DOWN = 0x20000; /** * Flag indicating that this view is the default-focus view. * * @see #isFocusedByDefault() * @see #setFocusedByDefault(boolean) */ private static final int PFLAG3_FOCUSED_BY_DEFAULT = 0x40000; /** * Whether this view has rendered elements that overlap (see {@link * #hasOverlappingRendering()}, {@link #forceHasOverlappingRendering(boolean)}, and Loading Loading @@ -4765,6 +4774,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setKeyboardNavigationSection(a.getBoolean(attr, true)); } break; case R.styleable.View_focusedByDefault: if (a.peekValue(attr) != null) { setFocusedByDefault(a.getBoolean(attr, true)); } break; } } Loading Loading @@ -6156,8 +6170,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mParent != null) { mParent.requestChildFocus(this, this); if (!isKeyboardNavigationCluster() && mParent instanceof ViewGroup) { ((ViewGroup) mParent).saveFocus(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).setDefaultFocus(this); } } Loading Loading @@ -9210,6 +9224,66 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } /** * Returns whether this View should receive focus when the focus is restored for the view * hierarchy containing this view. * <p> * Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a * window or serves as a target of cluster or section navigation. * * @see #restoreDefaultFocus(int) * * @return {@code true} if this view is the default-focus view, {@code false} otherwise * @attr ref android.R.styleable#View_focusedByDefault */ @ViewDebug.ExportedProperty(category = "focusedByDefault") public final boolean isFocusedByDefault() { return (mPrivateFlags3 & PFLAG3_FOCUSED_BY_DEFAULT) != 0; } /** * Sets whether this View should receive focus when the focus is restored for the view * hierarchy containing this view. * <p> * Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a * window or serves as a target of cluster or section navigation. * * @param isFocusedByDefault {@code true} to set this view as the default-focus view, * {@code false} otherwise. * * @see #restoreDefaultFocus(int) * * @attr ref android.R.styleable#View_focusedByDefault */ public void setFocusedByDefault(boolean isFocusedByDefault) { if (isFocusedByDefault == ((mPrivateFlags3 & PFLAG3_FOCUSED_BY_DEFAULT) != 0)) { return; } if (isFocusedByDefault) { mPrivateFlags3 |= PFLAG3_FOCUSED_BY_DEFAULT; } else { mPrivateFlags3 &= ~PFLAG3_FOCUSED_BY_DEFAULT; } if (mParent instanceof ViewGroup) { if (isFocusedByDefault) { ((ViewGroup) mParent).setDefaultFocus(this); } else { ((ViewGroup) mParent).cleanDefaultFocus(this); } } } /** * Returns whether the view hierarchy with this view as a root contain a default-focus view. * * @return {@code true} if this view has default focus, {@code false} otherwise */ boolean hasDefaultFocus() { return isFocusedByDefault(); } /** * Find the nearest keyboard navigation group in the specified direction. The group type can be * either a cluster or a section. Loading Loading @@ -9586,15 +9660,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** * Gives focus to the last focused view in the view hierarchy that has this view as a root. * If the last focused view cannot be found, fall back to calling {@link #requestFocus()}. * Nested keyboard navigation clusters are excluded from the hierarchy considered for saving the * last focus. * 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(int)}. * Nested keyboard navigation clusters are excluded from the hierarchy. * * @return Whether this view or one of its descendants actually took focus. * @param direction The direction of the focus * @return Whether this view or one of its descendants actually took focus */ public boolean restoreLastFocus() { return requestFocus(); public boolean restoreDefaultFocus(@FocusDirection int direction) { return requestFocus(direction); } /** Loading core/java/android/view/ViewGroup.java +59 −25 Original line number Diff line number Diff line Loading @@ -136,9 +136,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // The view contained within this ViewGroup that has or contains focus. private View mFocused; // The last view contained within this ViewGroup (excluding nested keyboard navigation clusters) // that had or contained focus. private View mLastFocused; // The view contained within this ViewGroup (excluding nested keyboard navigation clusters) // that is or contains a default-focus view. private View mDefaultFocus; /** * A Transformation used when drawing children, to Loading Loading @@ -722,7 +722,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (mFocused != null) { mFocused.unFocus(this); mFocused = null; mLastFocused = null; mDefaultFocus = null; } super.handleFocusGainInternal(direction, previouslyFocusedRect); } Loading Loading @@ -753,19 +753,47 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** * Saves the current focus as the last focus for this view and all its ancestors. * Sets the specified child view as the default focus for this view and all its ancestors. * If the view is inside a keyboard navigation cluster, stops at the root of the cluster since * the cluster forms a separate keyboard navigation hierarchy from the focus saving point of * the cluster forms a separate keyboard navigation hierarchy from the default focus point of * view. */ void saveFocus() { mLastFocused = mFocused; void setDefaultFocus(View child) { if (child.isKeyboardNavigationCluster()) { return; } mDefaultFocus = child; if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).setDefaultFocus(this); } } /** * Destroys the default focus chain. */ void cleanDefaultFocus(View child) { if (mDefaultFocus != child) { return; } if (child.isKeyboardNavigationCluster()) { return; } mDefaultFocus = null; if (!isKeyboardNavigationCluster() && mParent instanceof ViewGroup) { ((ViewGroup) mParent).saveFocus(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).cleanDefaultFocus(this); } } @Override boolean hasDefaultFocus() { return mDefaultFocus != null || super.hasDefaultFocus(); } @Override public void focusableViewAvailable(View v) { if (mParent != null Loading Loading @@ -3054,14 +3082,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } @Override public boolean restoreLastFocus() { if (mLastFocused != null && !mLastFocused.isKeyboardNavigationCluster() public boolean restoreDefaultFocus(@FocusDirection int direction) { if (mDefaultFocus != null && !mDefaultFocus.isKeyboardNavigationCluster() && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS && (mLastFocused.mViewFlags & VISIBILITY_MASK) == VISIBLE && mLastFocused.restoreLastFocus()) { && (mDefaultFocus.mViewFlags & VISIBILITY_MASK) == VISIBLE && mDefaultFocus.restoreDefaultFocus(direction)) { return true; } return super.restoreLastFocus(); return super.restoreDefaultFocus(direction); } /** Loading Loading @@ -4720,6 +4748,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (mCurrentDragStartEvent != null && child.getVisibility() == VISIBLE) { notifyChildOfDragStart(child); } if (child.hasDefaultFocus()) { // When adding a child that contains default focus, either during inflation or while // manually assembling the hierarchy, update the ancestor default-focus chain. setDefaultFocus(child); } } private void addInArray(View child, int index) { Loading Loading @@ -4931,8 +4965,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.unFocus(null); clearChildFocus = true; } if (view == mLastFocused) { mLastFocused = null; if (view == mDefaultFocus) { mDefaultFocus = null; } view.clearAccessibilityFocus(); Loading Loading @@ -5044,8 +5078,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.unFocus(null); clearChildFocus = true; } if (view == mLastFocused) { mLastFocused = null; if (view == mDefaultFocus) { mDefaultFocus = null; } view.clearAccessibilityFocus(); Loading Loading @@ -5120,7 +5154,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager boolean clearChildFocus = false; needGlobalAttributesUpdate(false); mLastFocused = null; mDefaultFocus = null; for (int i = count - 1; i >= 0; i--) { final View view = children[i]; Loading Loading @@ -5192,8 +5226,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child == mFocused) { child.clearFocus(); } if (child == mLastFocused) { mLastFocused = null; if (child == mDefaultFocus) { mDefaultFocus = null; } child.clearAccessibilityFocus(); Loading Loading @@ -6276,11 +6310,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager Log.d(VIEW_LOG_TAG, output); mFocused.debug(depth + 1); } if (mLastFocused != null) { if (mDefaultFocus != null) { output = debugIndent(depth); output += "mLastFocused"; output += "mDefaultFocus"; Log.d(VIEW_LOG_TAG, output); mLastFocused.debug(depth + 1); mDefaultFocus.debug(depth + 1); } if (mChildrenCount != 0) { output = debugIndent(depth); Loading Loading
api/current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -584,6 +584,7 @@ package android { field public static final int flipInterval = 16843129; // 0x1010179 field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedByDefault = 16844101; // 0x1010545 field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac Loading Loading @@ -43512,6 +43513,7 @@ package android.view { method public final boolean isFocusable(); method public final boolean isFocusableInTouchMode(); method public boolean isFocused(); method public final boolean isFocusedByDefault(); method public boolean isHapticFeedbackEnabled(); method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); Loading Loading @@ -43642,8 +43644,8 @@ package android.view { method public final void requestUnbufferedDispatch(android.view.MotionEvent); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(int); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public boolean restoreLastFocus(); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); method public void scrollBy(int, int); Loading Loading @@ -43681,6 +43683,7 @@ package android.view { method public void setFitsSystemWindows(boolean); method public void setFocusable(boolean); method public void setFocusableInTouchMode(boolean); method public void setFocusedByDefault(boolean); method public void setForeground(android.graphics.drawable.Drawable); method public void setForegroundGravity(int); method public void setForegroundTintList(android.content.res.ColorStateList);
api/system-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ package android { field public static final int flipInterval = 16843129; // 0x1010179 field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedByDefault = 16844101; // 0x1010545 field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac Loading Loading @@ -46736,6 +46737,7 @@ package android.view { method public final boolean isFocusable(); method public final boolean isFocusableInTouchMode(); method public boolean isFocused(); method public final boolean isFocusedByDefault(); method public boolean isHapticFeedbackEnabled(); method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); Loading Loading @@ -46866,8 +46868,8 @@ package android.view { method public final void requestUnbufferedDispatch(android.view.MotionEvent); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(int); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public boolean restoreLastFocus(); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); method public void scrollBy(int, int); Loading Loading @@ -46905,6 +46907,7 @@ package android.view { method public void setFitsSystemWindows(boolean); method public void setFocusable(boolean); method public void setFocusableInTouchMode(boolean); method public void setFocusedByDefault(boolean); method public void setForeground(android.graphics.drawable.Drawable); method public void setForegroundGravity(int); method public void setForegroundTintList(android.content.res.ColorStateList);
api/test-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -584,6 +584,7 @@ package android { field public static final int flipInterval = 16843129; // 0x1010179 field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedByDefault = 16844101; // 0x1010545 field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac Loading Loading @@ -43802,6 +43803,7 @@ package android.view { method public final boolean isFocusable(); method public final boolean isFocusableInTouchMode(); method public boolean isFocused(); method public final boolean isFocusedByDefault(); method public boolean isHapticFeedbackEnabled(); method public boolean isHardwareAccelerated(); method public boolean isHorizontalFadingEdgeEnabled(); Loading Loading @@ -43932,8 +43934,8 @@ package android.view { method public final void requestUnbufferedDispatch(android.view.MotionEvent); method public static int resolveSize(int, int); method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(int); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public boolean restoreLastFocus(); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); method public void scrollBy(int, int); Loading Loading @@ -43971,6 +43973,7 @@ package android.view { method public void setFitsSystemWindows(boolean); method public void setFocusable(boolean); method public void setFocusableInTouchMode(boolean); method public void setFocusedByDefault(boolean); method public void setForeground(android.graphics.drawable.Drawable); method public void setForegroundGravity(int); method public void setForegroundTintList(android.content.res.ColorStateList);
core/java/android/view/View.java +84 −10 Original line number Diff line number Diff line Loading @@ -2502,7 +2502,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG3_CLUSTER * 1 PFLAG3_SECTION * 1 PFLAG3_FINGER_DOWN * xxxxx * NO LONGER NEEDED, SHOULD BE REUSED * * 1 PFLAG3_FOCUSED_BY_DEFAULT * xxxx * NO LONGER NEEDED, SHOULD BE REUSED * * 1 PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE * 1 PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED * 1 PFLAG3_TEMPORARY_DETACH Loading Loading @@ -2722,6 +2723,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static final int PFLAG3_FINGER_DOWN = 0x20000; /** * Flag indicating that this view is the default-focus view. * * @see #isFocusedByDefault() * @see #setFocusedByDefault(boolean) */ private static final int PFLAG3_FOCUSED_BY_DEFAULT = 0x40000; /** * Whether this view has rendered elements that overlap (see {@link * #hasOverlappingRendering()}, {@link #forceHasOverlappingRendering(boolean)}, and Loading Loading @@ -4765,6 +4774,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setKeyboardNavigationSection(a.getBoolean(attr, true)); } break; case R.styleable.View_focusedByDefault: if (a.peekValue(attr) != null) { setFocusedByDefault(a.getBoolean(attr, true)); } break; } } Loading Loading @@ -6156,8 +6170,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (mParent != null) { mParent.requestChildFocus(this, this); if (!isKeyboardNavigationCluster() && mParent instanceof ViewGroup) { ((ViewGroup) mParent).saveFocus(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).setDefaultFocus(this); } } Loading Loading @@ -9210,6 +9224,66 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } /** * Returns whether this View should receive focus when the focus is restored for the view * hierarchy containing this view. * <p> * Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a * window or serves as a target of cluster or section navigation. * * @see #restoreDefaultFocus(int) * * @return {@code true} if this view is the default-focus view, {@code false} otherwise * @attr ref android.R.styleable#View_focusedByDefault */ @ViewDebug.ExportedProperty(category = "focusedByDefault") public final boolean isFocusedByDefault() { return (mPrivateFlags3 & PFLAG3_FOCUSED_BY_DEFAULT) != 0; } /** * Sets whether this View should receive focus when the focus is restored for the view * hierarchy containing this view. * <p> * Focus gets restored for a view hierarchy when the root of the hierarchy gets added to a * window or serves as a target of cluster or section navigation. * * @param isFocusedByDefault {@code true} to set this view as the default-focus view, * {@code false} otherwise. * * @see #restoreDefaultFocus(int) * * @attr ref android.R.styleable#View_focusedByDefault */ public void setFocusedByDefault(boolean isFocusedByDefault) { if (isFocusedByDefault == ((mPrivateFlags3 & PFLAG3_FOCUSED_BY_DEFAULT) != 0)) { return; } if (isFocusedByDefault) { mPrivateFlags3 |= PFLAG3_FOCUSED_BY_DEFAULT; } else { mPrivateFlags3 &= ~PFLAG3_FOCUSED_BY_DEFAULT; } if (mParent instanceof ViewGroup) { if (isFocusedByDefault) { ((ViewGroup) mParent).setDefaultFocus(this); } else { ((ViewGroup) mParent).cleanDefaultFocus(this); } } } /** * Returns whether the view hierarchy with this view as a root contain a default-focus view. * * @return {@code true} if this view has default focus, {@code false} otherwise */ boolean hasDefaultFocus() { return isFocusedByDefault(); } /** * Find the nearest keyboard navigation group in the specified direction. The group type can be * either a cluster or a section. Loading Loading @@ -9586,15 +9660,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** * Gives focus to the last focused view in the view hierarchy that has this view as a root. * If the last focused view cannot be found, fall back to calling {@link #requestFocus()}. * Nested keyboard navigation clusters are excluded from the hierarchy considered for saving the * last focus. * 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(int)}. * Nested keyboard navigation clusters are excluded from the hierarchy. * * @return Whether this view or one of its descendants actually took focus. * @param direction The direction of the focus * @return Whether this view or one of its descendants actually took focus */ public boolean restoreLastFocus() { return requestFocus(); public boolean restoreDefaultFocus(@FocusDirection int direction) { return requestFocus(direction); } /** Loading
core/java/android/view/ViewGroup.java +59 −25 Original line number Diff line number Diff line Loading @@ -136,9 +136,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // The view contained within this ViewGroup that has or contains focus. private View mFocused; // The last view contained within this ViewGroup (excluding nested keyboard navigation clusters) // that had or contained focus. private View mLastFocused; // The view contained within this ViewGroup (excluding nested keyboard navigation clusters) // that is or contains a default-focus view. private View mDefaultFocus; /** * A Transformation used when drawing children, to Loading Loading @@ -722,7 +722,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (mFocused != null) { mFocused.unFocus(this); mFocused = null; mLastFocused = null; mDefaultFocus = null; } super.handleFocusGainInternal(direction, previouslyFocusedRect); } Loading Loading @@ -753,19 +753,47 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** * Saves the current focus as the last focus for this view and all its ancestors. * Sets the specified child view as the default focus for this view and all its ancestors. * If the view is inside a keyboard navigation cluster, stops at the root of the cluster since * the cluster forms a separate keyboard navigation hierarchy from the focus saving point of * the cluster forms a separate keyboard navigation hierarchy from the default focus point of * view. */ void saveFocus() { mLastFocused = mFocused; void setDefaultFocus(View child) { if (child.isKeyboardNavigationCluster()) { return; } mDefaultFocus = child; if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).setDefaultFocus(this); } } /** * Destroys the default focus chain. */ void cleanDefaultFocus(View child) { if (mDefaultFocus != child) { return; } if (child.isKeyboardNavigationCluster()) { return; } mDefaultFocus = null; if (!isKeyboardNavigationCluster() && mParent instanceof ViewGroup) { ((ViewGroup) mParent).saveFocus(); if (mParent instanceof ViewGroup) { ((ViewGroup) mParent).cleanDefaultFocus(this); } } @Override boolean hasDefaultFocus() { return mDefaultFocus != null || super.hasDefaultFocus(); } @Override public void focusableViewAvailable(View v) { if (mParent != null Loading Loading @@ -3054,14 +3082,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } @Override public boolean restoreLastFocus() { if (mLastFocused != null && !mLastFocused.isKeyboardNavigationCluster() public boolean restoreDefaultFocus(@FocusDirection int direction) { if (mDefaultFocus != null && !mDefaultFocus.isKeyboardNavigationCluster() && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS && (mLastFocused.mViewFlags & VISIBILITY_MASK) == VISIBLE && mLastFocused.restoreLastFocus()) { && (mDefaultFocus.mViewFlags & VISIBILITY_MASK) == VISIBLE && mDefaultFocus.restoreDefaultFocus(direction)) { return true; } return super.restoreLastFocus(); return super.restoreDefaultFocus(direction); } /** Loading Loading @@ -4720,6 +4748,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (mCurrentDragStartEvent != null && child.getVisibility() == VISIBLE) { notifyChildOfDragStart(child); } if (child.hasDefaultFocus()) { // When adding a child that contains default focus, either during inflation or while // manually assembling the hierarchy, update the ancestor default-focus chain. setDefaultFocus(child); } } private void addInArray(View child, int index) { Loading Loading @@ -4931,8 +4965,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.unFocus(null); clearChildFocus = true; } if (view == mLastFocused) { mLastFocused = null; if (view == mDefaultFocus) { mDefaultFocus = null; } view.clearAccessibilityFocus(); Loading Loading @@ -5044,8 +5078,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.unFocus(null); clearChildFocus = true; } if (view == mLastFocused) { mLastFocused = null; if (view == mDefaultFocus) { mDefaultFocus = null; } view.clearAccessibilityFocus(); Loading Loading @@ -5120,7 +5154,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager boolean clearChildFocus = false; needGlobalAttributesUpdate(false); mLastFocused = null; mDefaultFocus = null; for (int i = count - 1; i >= 0; i--) { final View view = children[i]; Loading Loading @@ -5192,8 +5226,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child == mFocused) { child.clearFocus(); } if (child == mLastFocused) { mLastFocused = null; if (child == mDefaultFocus) { mDefaultFocus = null; } child.clearAccessibilityFocus(); Loading Loading @@ -6276,11 +6310,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager Log.d(VIEW_LOG_TAG, output); mFocused.debug(depth + 1); } if (mLastFocused != null) { if (mDefaultFocus != null) { output = debugIndent(depth); output += "mLastFocused"; output += "mDefaultFocus"; Log.d(VIEW_LOG_TAG, output); mLastFocused.debug(depth + 1); mDefaultFocus.debug(depth + 1); } if (mChildrenCount != 0) { output = debugIndent(depth); Loading