Loading core/java/android/view/View.java +12 −4 Original line number Original line Diff line number Diff line Loading @@ -10026,12 +10026,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Going from one cluster to another, so save last-focused. // Going from one cluster to another, so save last-focused. // This covers cluster jumps because they are always FOCUS_DOWN // This covers cluster jumps because they are always FOCUS_DOWN oldFocus.setFocusedInCluster(oldCluster); oldFocus.setFocusedInCluster(oldCluster); if (!(oldFocus.mParent instanceof ViewGroup)) { return; } if (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD) { if (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD) { // This is a result of ordered navigation so consider navigation through // This is a result of ordered navigation so consider navigation through // the previous cluster "complete" and clear its last-focused memory. // the previous cluster "complete" and clear its last-focused memory. if (oldFocus.mParent instanceof ViewGroup) { ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus); ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus); } } else if (oldFocus instanceof ViewGroup && ((ViewGroup) oldFocus).getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS && ViewRootImpl.isViewDescendantOf(this, oldFocus)) { // This means oldFocus is not focusable since it obviously has a focusable // child (this). Don't restore focus to it in the future. ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus); } } } } } } Loading Loading @@ -13088,7 +13096,7 @@ 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. if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) { if ((mParent != null)) { mParent.focusableViewAvailable(this); mParent.focusableViewAvailable(this); } } } } core/java/android/view/ViewGroup.java +26 −14 Original line number Original line Diff line number Diff line Loading @@ -833,8 +833,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void focusableViewAvailable(View v) { public void focusableViewAvailable(View v) { if (mParent != null if (mParent != null // shortcut: don't report a new focusable view if we block our descendants from // shortcut: don't report a new focusable view if we block our descendants from // getting focus // getting focus or if we're not visible && (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS) && (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS) && ((mViewFlags & VISIBILITY_MASK) == VISIBLE) && (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen()) && (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen()) // shortcut: don't report a new focusable view if we already are focused // shortcut: don't report a new focusable view if we already are focused // (and we don't prefer our descendants) // (and we don't prefer our descendants) Loading Loading @@ -1159,6 +1160,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // Determine whether we have a focused descendant. // Determine whether we have a focused descendant. final int descendantFocusability = getDescendantFocusability(); final int descendantFocusability = getDescendantFocusability(); if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) { if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) { return hasFocusableChild(dispatchExplicit); } return false; } boolean hasFocusableChild(boolean dispatchExplicit) { // Determine whether we have a focusable descendant. final int count = mChildrenCount; final int count = mChildrenCount; final View[] children = mChildren; final View[] children = mChildren; Loading @@ -1172,7 +1181,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; return true; } } } } } return false; return false; } } Loading Loading @@ -3230,7 +3238,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // will refer to a view not-in a cluster. // will refer to a view not-in a cluster. return restoreFocusInCluster(View.FOCUS_DOWN); return restoreFocusInCluster(View.FOCUS_DOWN); } } if (isKeyboardNavigationCluster()) { if (isKeyboardNavigationCluster() || (mViewFlags & VISIBILITY_MASK) != VISIBLE) { return false; return false; } } int descendentFocusability = getDescendantFocusability(); int descendentFocusability = getDescendantFocusability(); Loading @@ -3248,7 +3256,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; return true; } } } } if (descendentFocusability == FOCUS_AFTER_DESCENDANTS) { if (descendentFocusability == FOCUS_AFTER_DESCENDANTS && !hasFocusableChild(false)) { return super.requestFocus(FOCUS_DOWN, null); return super.requestFocus(FOCUS_DOWN, null); } } return false; return false; Loading Loading @@ -4915,7 +4923,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.mParent = this; child.mParent = this; } } if (child.hasFocus()) { final boolean childHasFocus = child.hasFocus(); if (childHasFocus) { requestChildFocus(child, child.findFocus()); requestChildFocus(child, child.findFocus()); } } Loading @@ -4928,6 +4937,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager needGlobalAttributesUpdate(true); needGlobalAttributesUpdate(true); } } ai.mKeepScreenOn = lastKeepOn; ai.mKeepScreenOn = lastKeepOn; if (!childHasFocus && child.hasFocusable()) { focusableViewAvailable(child); } } } if (child.isLayoutDirectionInherited()) { if (child.isLayoutDirectionInherited()) { Loading Loading
core/java/android/view/View.java +12 −4 Original line number Original line Diff line number Diff line Loading @@ -10026,12 +10026,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Going from one cluster to another, so save last-focused. // Going from one cluster to another, so save last-focused. // This covers cluster jumps because they are always FOCUS_DOWN // This covers cluster jumps because they are always FOCUS_DOWN oldFocus.setFocusedInCluster(oldCluster); oldFocus.setFocusedInCluster(oldCluster); if (!(oldFocus.mParent instanceof ViewGroup)) { return; } if (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD) { if (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD) { // This is a result of ordered navigation so consider navigation through // This is a result of ordered navigation so consider navigation through // the previous cluster "complete" and clear its last-focused memory. // the previous cluster "complete" and clear its last-focused memory. if (oldFocus.mParent instanceof ViewGroup) { ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus); ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus); } } else if (oldFocus instanceof ViewGroup && ((ViewGroup) oldFocus).getDescendantFocusability() == ViewGroup.FOCUS_AFTER_DESCENDANTS && ViewRootImpl.isViewDescendantOf(this, oldFocus)) { // This means oldFocus is not focusable since it obviously has a focusable // child (this). Don't restore focus to it in the future. ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus); } } } } } } Loading Loading @@ -13088,7 +13096,7 @@ 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. if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) { if ((mParent != null)) { mParent.focusableViewAvailable(this); mParent.focusableViewAvailable(this); } } } }
core/java/android/view/ViewGroup.java +26 −14 Original line number Original line Diff line number Diff line Loading @@ -833,8 +833,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void focusableViewAvailable(View v) { public void focusableViewAvailable(View v) { if (mParent != null if (mParent != null // shortcut: don't report a new focusable view if we block our descendants from // shortcut: don't report a new focusable view if we block our descendants from // getting focus // getting focus or if we're not visible && (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS) && (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS) && ((mViewFlags & VISIBILITY_MASK) == VISIBLE) && (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen()) && (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen()) // shortcut: don't report a new focusable view if we already are focused // shortcut: don't report a new focusable view if we already are focused // (and we don't prefer our descendants) // (and we don't prefer our descendants) Loading Loading @@ -1159,6 +1160,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // Determine whether we have a focused descendant. // Determine whether we have a focused descendant. final int descendantFocusability = getDescendantFocusability(); final int descendantFocusability = getDescendantFocusability(); if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) { if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) { return hasFocusableChild(dispatchExplicit); } return false; } boolean hasFocusableChild(boolean dispatchExplicit) { // Determine whether we have a focusable descendant. final int count = mChildrenCount; final int count = mChildrenCount; final View[] children = mChildren; final View[] children = mChildren; Loading @@ -1172,7 +1181,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; return true; } } } } } return false; return false; } } Loading Loading @@ -3230,7 +3238,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // will refer to a view not-in a cluster. // will refer to a view not-in a cluster. return restoreFocusInCluster(View.FOCUS_DOWN); return restoreFocusInCluster(View.FOCUS_DOWN); } } if (isKeyboardNavigationCluster()) { if (isKeyboardNavigationCluster() || (mViewFlags & VISIBILITY_MASK) != VISIBLE) { return false; return false; } } int descendentFocusability = getDescendantFocusability(); int descendentFocusability = getDescendantFocusability(); Loading @@ -3248,7 +3256,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; return true; } } } } if (descendentFocusability == FOCUS_AFTER_DESCENDANTS) { if (descendentFocusability == FOCUS_AFTER_DESCENDANTS && !hasFocusableChild(false)) { return super.requestFocus(FOCUS_DOWN, null); return super.requestFocus(FOCUS_DOWN, null); } } return false; return false; Loading Loading @@ -4915,7 +4923,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.mParent = this; child.mParent = this; } } if (child.hasFocus()) { final boolean childHasFocus = child.hasFocus(); if (childHasFocus) { requestChildFocus(child, child.findFocus()); requestChildFocus(child, child.findFocus()); } } Loading @@ -4928,6 +4937,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager needGlobalAttributesUpdate(true); needGlobalAttributesUpdate(true); } } ai.mKeepScreenOn = lastKeepOn; ai.mKeepScreenOn = lastKeepOn; if (!childHasFocus && child.hasFocusable()) { focusableViewAvailable(child); } } } if (child.isLayoutDirectionInherited()) { if (child.isLayoutDirectionInherited()) { Loading