Merge "Improve consistency in focusAfterDescendants behavior" into oc-dev
am: 12ee4bd7a8
Change-Id: I46212487711efebe8efa95bfa28f24e8ee24a2cf
This commit is contained in:
@@ -10028,12 +10028,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
// Going from one cluster to another, so save last-focused.
|
||||
// This covers cluster jumps because they are always FOCUS_DOWN
|
||||
oldFocus.setFocusedInCluster(oldCluster);
|
||||
if (!(oldFocus.mParent instanceof ViewGroup)) {
|
||||
return;
|
||||
}
|
||||
if (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD) {
|
||||
// This is a result of ordered navigation so consider navigation through
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13080,7 +13088,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
// about in case nothing has focus. even if this specific view
|
||||
// isn't focusable, it may contain something that is, so let
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,8 +833,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
public void focusableViewAvailable(View v) {
|
||||
if (mParent != null
|
||||
// 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)
|
||||
&& ((mViewFlags & VISIBILITY_MASK) == VISIBLE)
|
||||
&& (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen())
|
||||
// shortcut: don't report a new focusable view if we already are focused
|
||||
// (and we don't prefer our descendants)
|
||||
@@ -1159,18 +1160,25 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
// Determine whether we have a focused descendant.
|
||||
final int descendantFocusability = getDescendantFocusability();
|
||||
if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
|
||||
final int count = mChildrenCount;
|
||||
final View[] children = mChildren;
|
||||
return hasFocusableChild(dispatchExplicit);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = children[i];
|
||||
return false;
|
||||
}
|
||||
|
||||
// In case the subclass has overridden has[Explicit]Focusable, dispatch
|
||||
// to the expected one for each child even though we share logic here.
|
||||
if ((dispatchExplicit && child.hasExplicitFocusable())
|
||||
|| (!dispatchExplicit && child.hasFocusable())) {
|
||||
return true;
|
||||
}
|
||||
boolean hasFocusableChild(boolean dispatchExplicit) {
|
||||
// Determine whether we have a focusable descendant.
|
||||
final int count = mChildrenCount;
|
||||
final View[] children = mChildren;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = children[i];
|
||||
|
||||
// In case the subclass has overridden has[Explicit]Focusable, dispatch
|
||||
// to the expected one for each child even though we share logic here.
|
||||
if ((dispatchExplicit && child.hasExplicitFocusable())
|
||||
|| (!dispatchExplicit && child.hasFocusable())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3230,7 +3238,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
// will refer to a view not-in a cluster.
|
||||
return restoreFocusInCluster(View.FOCUS_DOWN);
|
||||
}
|
||||
if (isKeyboardNavigationCluster()) {
|
||||
if (isKeyboardNavigationCluster() || (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
int descendentFocusability = getDescendantFocusability();
|
||||
@@ -3248,7 +3256,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (descendentFocusability == FOCUS_AFTER_DESCENDANTS) {
|
||||
if (descendentFocusability == FOCUS_AFTER_DESCENDANTS && !hasFocusableChild(false)) {
|
||||
return super.requestFocus(FOCUS_DOWN, null);
|
||||
}
|
||||
return false;
|
||||
@@ -4914,7 +4922,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
child.mParent = this;
|
||||
}
|
||||
|
||||
if (child.hasFocus()) {
|
||||
final boolean childHasFocus = child.hasFocus();
|
||||
if (childHasFocus) {
|
||||
requestChildFocus(child, child.findFocus());
|
||||
}
|
||||
|
||||
@@ -4927,6 +4936,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
needGlobalAttributesUpdate(true);
|
||||
}
|
||||
ai.mKeepScreenOn = lastKeepOn;
|
||||
if (!childHasFocus && child.hasFocusable()) {
|
||||
focusableViewAvailable(child);
|
||||
}
|
||||
}
|
||||
|
||||
if (child.isLayoutDirectionInherited()) {
|
||||
|
||||
Reference in New Issue
Block a user