OSDN Git Service

Use clearFocus() when entering touch mode
authorAlan Viverette <alanv@google.com>
Wed, 24 Jul 2013 22:49:23 +0000 (15:49 -0700)
committerAlan Viverette <alanv@google.com>
Wed, 24 Jul 2013 22:49:23 +0000 (15:49 -0700)
Calling unFocus() leaves the view hierarchy in an inconsistent
state. This is okay in ViewGroup, where the state is manually
updated, but causes issues in ViewRootImpl.

BUG: 9983358
Change-Id: Id63e62962d895e6bd4f816f202dcf77254ceab4e

core/java/android/view/View.java
core/java/android/view/ViewRootImpl.java

index 188ddf2..555e883 100644 (file)
@@ -4588,6 +4588,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     /**
      * Called internally by the view system when a new view is getting focus.
      * This is what clears the old focus.
+     * <p>
+     * <b>NOTE:</b> The parent view's focused child must be updated manually
+     * after calling this method. Otherwise, the view hierarchy may be left in
+     * an inconstent state.
      */
     void unFocus() {
         if (DBG) {
index 075719c..1f7ff9b 100644 (file)
@@ -3250,24 +3250,23 @@ public final class ViewRootImpl implements ViewParent,
     }
 
     private boolean enterTouchMode() {
-        if (mView != null) {
-            if (mView.hasFocus()) {
-                // note: not relying on mFocusedView here because this could
-                // be when the window is first being added, and mFocused isn't
-                // set yet.
-                final View focused = mView.findFocus();
-                if (focused != null && !focused.isFocusableInTouchMode()) {
-                    final ViewGroup ancestorToTakeFocus =
-                            findAncestorToTakeFocusInTouchMode(focused);
-                    if (ancestorToTakeFocus != null) {
-                        // there is an ancestor that wants focus after its descendants that
-                        // is focusable in touch mode.. give it focus
-                        return ancestorToTakeFocus.requestFocus();
-                    } else {
-                        // nothing appropriate to have focus in touch mode, clear it out
-                        focused.unFocus();
-                        return true;
-                    }
+        if (mView != null && mView.hasFocus()) {
+            // note: not relying on mFocusedView here because this could
+            // be when the window is first being added, and mFocused isn't
+            // set yet.
+            final View focused = mView.findFocus();
+            if (focused != null && !focused.isFocusableInTouchMode()) {
+                final ViewGroup ancestorToTakeFocus = findAncestorToTakeFocusInTouchMode(focused);
+                if (ancestorToTakeFocus != null) {
+                    // there is an ancestor that wants focus after its
+                    // descendants that is focusable in touch mode.. give it
+                    // focus
+                    return ancestorToTakeFocus.requestFocus();
+                } else {
+                    // nothing appropriate to have focus in touch mode, clear it
+                    // out
+                    focused.clearFocus();
+                    return true;
                 }
             }
         }