summaryrefslogtreecommitdiffstats
path: root/core/java/android/view
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2012-01-30 16:37:33 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-01-30 16:37:33 -0800
commit12df3cf156885a421beccfa6b6e20fd1a188847a (patch)
treeb72fe4d32ebffbadf5006e525a1027aeb3c380fb /core/java/android/view
parentf68af846d472e59f1a8280f250a1f0b9ac13abd9 (diff)
parentc6fd88e213703a581fe4680259981f09ae0444f2 (diff)
downloadframeworks_base-12df3cf156885a421beccfa6b6e20fd1a188847a.zip
frameworks_base-12df3cf156885a421beccfa6b6e20fd1a188847a.tar.gz
frameworks_base-12df3cf156885a421beccfa6b6e20fd1a188847a.tar.bz2
Merge "Incorrect behavior of View clear focus."
Diffstat (limited to 'core/java/android/view')
-rw-r--r--core/java/android/view/View.java23
-rw-r--r--core/java/android/view/ViewGroup.java19
-rw-r--r--core/java/android/view/ViewRootImpl.java35
3 files changed, 53 insertions, 24 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 39f603d..343891a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3770,6 +3770,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
if ((mPrivateFlags & FOCUSED) != 0) {
+ // If this is the first focusable do not clear focus since the we
+ // try to give it focus every time a view clears its focus. Hence,
+ // the view that would gain focus already has it.
+ View firstFocusable = getFirstFocusable();
+ if (firstFocusable == this) {
+ return;
+ }
+
mPrivateFlags &= ~FOCUSED;
if (mParent != null) {
@@ -3778,9 +3786,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
onFocusChanged(false, 0, null);
refreshDrawableState();
+
+ // The view cleared focus and invoked the callbacks, so now is the
+ // time to give focus to the the first focusable to ensure that the
+ // gain focus is announced after clear focus.
+ if (firstFocusable != null) {
+ firstFocusable.requestFocus(FOCUS_FORWARD);
+ }
}
}
+ private View getFirstFocusable() {
+ ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot != null) {
+ return viewRoot.focusSearch(null, FOCUS_FORWARD);
+ }
+ return null;
+ }
+
/**
* Called to clear the focus of a view that is about to be removed.
* Doesn't call clearChildFocus, which prevents this view from taking
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d906a16..7559862 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -675,11 +675,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
@Override
public void clearFocus() {
- super.clearFocus();
-
- // clear any child focus if it exists
- if (mFocused != null) {
+ if (DBG) {
+ System.out.println(this + " clearFocus()");
+ }
+ if (mFocused == null) {
+ super.clearFocus();
+ } else {
mFocused.clearFocus();
+ mFocused = null;
}
}
@@ -691,12 +694,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (DBG) {
System.out.println(this + " unFocus()");
}
-
- super.unFocus();
- if (mFocused != null) {
+ if (mFocused == null) {
+ super.unFocus();
+ } else {
mFocused.unFocus();
+ mFocused = null;
}
- mFocused = null;
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1a4bdf4..2ef843b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -168,6 +168,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
View mView;
View mFocusedView;
View mRealFocusedView; // this is not set to null in touch mode
+ View mOldFocusedView;
int mViewVisibility;
boolean mAppVisible = true;
int mOrigWindowType = -1;
@@ -2226,32 +2227,33 @@ public final class ViewRootImpl extends Handler implements ViewParent,
public void requestChildFocus(View child, View focused) {
checkThread();
- if (mFocusedView != focused) {
- mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mFocusedView, focused);
- scheduleTraversals();
+
+ if (DEBUG_INPUT_RESIZE) {
+ Log.v(TAG, "Request child focus: focus now " + focused);
}
+
+ mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, focused);
+ scheduleTraversals();
+
mFocusedView = mRealFocusedView = focused;
- if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Request child focus: focus now "
- + mFocusedView);
}
public void clearChildFocus(View child) {
checkThread();
- View oldFocus = mFocusedView;
+ if (DEBUG_INPUT_RESIZE) {
+ Log.v(TAG, "Clearing child focus");
+ }
+
+ mOldFocusedView = mFocusedView;
- if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Clearing child focus");
- mFocusedView = mRealFocusedView = null;
- if (mView != null && !mView.hasFocus()) {
- // If a view gets the focus, the listener will be invoked from requestChildFocus()
- if (!mView.requestFocus(View.FOCUS_FORWARD)) {
- mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
- }
- } else if (oldFocus != null) {
- mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
+ // Invoke the listener only if there is no view to take focus
+ if (focusSearch(null, View.FOCUS_FORWARD) == null) {
+ mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, null);
}
- }
+ mFocusedView = mRealFocusedView = null;
+ }
public void focusableViewAvailable(View v) {
checkThread();
@@ -2724,6 +2726,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mView.unFocus();
mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(focused, null);
mFocusedView = null;
+ mOldFocusedView = null;
return true;
}
}