summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java37
-rw-r--r--core/java/android/view/ViewGroup.java11
2 files changed, 36 insertions, 12 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3121945195c5..07258fc30704 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6504,7 +6504,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mParent != null) {
mParent.requestChildFocus(this, this);
- setFocusedInCluster();
+ updateFocusedInCluster(oldFocus, direction);
}
if (mAttachInfo != null) {
@@ -9927,22 +9927,47 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public final void setFocusedInCluster() {
- View top = findKeyboardNavigationCluster();
- if (top == this) {
+ setFocusedInCluster(findKeyboardNavigationCluster());
+ }
+
+ private void setFocusedInCluster(View cluster) {
+ if (this instanceof ViewGroup) {
+ ((ViewGroup) this).mFocusedInCluster = null;
+ }
+ if (cluster == this) {
return;
}
ViewParent parent = mParent;
View child = this;
while (parent instanceof ViewGroup) {
- ((ViewGroup) parent).setFocusedInCluster(child);
- if (parent == top) {
- return;
+ ((ViewGroup) parent).mFocusedInCluster = child;
+ if (parent == cluster) {
+ break;
}
child = (View) parent;
parent = parent.getParent();
}
}
+ private void updateFocusedInCluster(View oldFocus, @FocusDirection int direction) {
+ if (oldFocus != null) {
+ View oldCluster = oldFocus.findKeyboardNavigationCluster();
+ View cluster = findKeyboardNavigationCluster();
+ if (oldCluster != cluster) {
+ // Going from one cluster to another, so save last-focused.
+ // This covers cluster jumps because they are always FOCUS_DOWN
+ oldFocus.setFocusedInCluster(oldCluster);
+ 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);
+ }
+ }
+ }
+ }
+ }
+
/**
* Returns whether this View should receive focus when the focus is restored for the view
* hierarchy containing this view.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 18c1b8c3ad22..50593f28d9e3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -142,7 +142,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// that is or contains a default-focus view.
private View mDefaultFocus;
// The last child of this ViewGroup which held focus within the current cluster
- private View mFocusedInCluster;
+ View mFocusedInCluster;
/**
* A Transformation used when drawing children, to
@@ -806,10 +806,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return mDefaultFocus != null || super.hasDefaultFocus();
}
- void setFocusedInCluster(View child) {
- mFocusedInCluster = child;
- }
-
/**
* Removes {@code child} (and associated focusedInCluster chain) from the cluster containing
* it.
@@ -825,8 +821,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
ViewParent parent = this;
do {
((ViewGroup) parent).mFocusedInCluster = null;
+ if (parent == top) {
+ break;
+ }
parent = parent.getParent();
- } while (parent != top && parent instanceof ViewGroup);
+ } while (parent instanceof ViewGroup);
}
@Override