Merge "Improve consistency in focusAfterDescendants behavior" into oc-dev

am: 12ee4bd7a8

Change-Id: I46212487711efebe8efa95bfa28f24e8ee24a2cf
This commit is contained in:
Evan Rosky
2017-06-02 18:04:10 +00:00
committed by android-build-merger
2 changed files with 38 additions and 18 deletions

View File

@@ -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);
}
}

View File

@@ -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()) {