Skip to content

Commit b39e509

Browse files
sganovAndroid (Google) Code Review
authored andcommitted
Merge "Fixing broken clear focus behavior."
2 parents a393bed + 57cadf2 commit b39e509

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

core/java/android/view/View.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4032,8 +4032,9 @@ public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
40324032
* <p>
40334033
* <strong>Note:</strong> When a View clears focus the framework is trying
40344034
* to give focus to the first focusable View from the top. Hence, if this
4035-
* View is the first from the top that can take focus, then its focus will
4036-
* not be cleared nor will the focus change callback be invoked.
4035+
* View is the first from the top that can take focus, then all callbacks
4036+
* related to clearing focus will be invoked after wich the framework will
4037+
* give focus to this view.
40374038
* </p>
40384039
*/
40394040
public void clearFocus() {
@@ -4050,25 +4051,22 @@ public void clearFocus() {
40504051

40514052
onFocusChanged(false, 0, null);
40524053
refreshDrawableState();
4054+
4055+
ensureInputFocusOnFirstFocusable();
40534056
}
40544057
}
40554058

4056-
/**
4057-
* Called to clear the focus of a view that is about to be removed.
4058-
* Doesn't call clearChildFocus, which prevents this view from taking
4059-
* focus again before it has been removed from the parent
4060-
*/
4061-
void clearFocusForRemoval() {
4062-
if ((mPrivateFlags & FOCUSED) != 0) {
4063-
mPrivateFlags &= ~FOCUSED;
4064-
4065-
onFocusChanged(false, 0, null);
4066-
refreshDrawableState();
4067-
4068-
// The view cleared focus and invoked the callbacks, so now is the
4069-
// time to give focus to the the first focusable from the top to
4070-
// ensure that the gain focus is announced after clear focus.
4071-
getRootView().requestFocus(FOCUS_FORWARD);
4059+
void ensureInputFocusOnFirstFocusable() {
4060+
View root = getRootView();
4061+
if (root != null) {
4062+
// Find the first focusble from the top.
4063+
View next = root.focusSearch(FOCUS_FORWARD);
4064+
if (next != null) {
4065+
// Giving focus to the found focusable will not
4066+
// perform a search since we found a view that is
4067+
// guaranteed to be able to take focus.
4068+
next.requestFocus(FOCUS_FORWARD);
4069+
}
40724070
}
40734071
}
40744072

core/java/android/view/ViewGroup.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3375,7 +3375,7 @@ private void removeViewInternal(int index, View view) {
33753375

33763376
boolean clearChildFocus = false;
33773377
if (view == mFocused) {
3378-
view.clearFocusForRemoval();
3378+
view.unFocus();
33793379
clearChildFocus = true;
33803380
}
33813381

@@ -3398,6 +3398,7 @@ private void removeViewInternal(int index, View view) {
33983398

33993399
if (clearChildFocus) {
34003400
clearChildFocus(view);
3401+
ensureInputFocusOnFirstFocusable();
34013402
}
34023403
}
34033404

@@ -3450,7 +3451,7 @@ private void removeViewsInternal(int start, int count) {
34503451
}
34513452

34523453
if (view == focused) {
3453-
view.clearFocusForRemoval();
3454+
view.unFocus();
34543455
clearChildFocus = view;
34553456
}
34563457

@@ -3474,6 +3475,7 @@ private void removeViewsInternal(int start, int count) {
34743475

34753476
if (clearChildFocus != null) {
34763477
clearChildFocus(clearChildFocus);
3478+
ensureInputFocusOnFirstFocusable();
34773479
}
34783480
}
34793481

@@ -3519,7 +3521,7 @@ public void removeAllViewsInLayout() {
35193521
}
35203522

35213523
if (view == focused) {
3522-
view.clearFocusForRemoval();
3524+
view.unFocus();
35233525
clearChildFocus = view;
35243526
}
35253527

@@ -3542,6 +3544,7 @@ public void removeAllViewsInLayout() {
35423544

35433545
if (clearChildFocus != null) {
35443546
clearChildFocus(clearChildFocus);
3547+
ensureInputFocusOnFirstFocusable();
35453548
}
35463549
}
35473550

0 commit comments

Comments
 (0)