OSDN Git Service

Don't focus search user-specified views which are invisible
authorEvan Rosky <erosky@google.com>
Mon, 1 May 2017 23:36:24 +0000 (16:36 -0700)
committerEvan Rosky <erosky@google.com>
Mon, 1 May 2017 23:36:24 +0000 (16:36 -0700)
While searching for next user-specified focus, skip over any
views which are not visible. This will continue searching down
the chain until it either finds a visible view or until the
chain ends (at which point the normal findNextFocus search is
used).

This was causing problems in apps like the wallpaper selector
where focus would get stuck because calling requestFocus on an
invisible view is a no-op.

Bug: 37789849
Test: Added CTS. Checked that focus no-longer gets stuck in
      wallpaper app.

Change-Id: I1a52143bd6c63364418fe6250e6c3f83e2e1c726

core/java/android/view/FocusFinder.java

index 1ccf16a..48e5ca9 100644 (file)
@@ -193,10 +193,14 @@ public class FocusFinder {
     private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
         // check for user specified next focus
         View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
-        if (userSetNextFocus != null && userSetNextFocus.isFocusable()
-                && (!userSetNextFocus.isInTouchMode()
-                        || userSetNextFocus.isFocusableInTouchMode())) {
-            return userSetNextFocus;
+        while (userSetNextFocus != null) {
+            if (userSetNextFocus.isFocusable()
+                    && userSetNextFocus.getVisibility() == View.VISIBLE
+                    && (!userSetNextFocus.isInTouchMode()
+                            || userSetNextFocus.isFocusableInTouchMode())) {
+                return userSetNextFocus;
+            }
+            userSetNextFocus = userSetNextFocus.findUserSetNextFocus(root, direction);
         }
         return null;
     }