Skip to content

Commit 9366a84

Browse files
imhappidsn5ft
authored andcommitted
[Search] Block keyboard focus on other views when SearchView is open
PiperOrigin-RevId: 814296973
1 parent 1867bb0 commit 9366a84

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

docs/components/Search.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,18 @@ so that screen readers such as TalkBack are able to announce their purpose or
301301
action. Text rendered in these components are automatically provided to
302302
accessibility services, so additional content labels are usually unnecessary.
303303

304+
`SearchView` also automatically handles its siblings' accessibility when shown,
305+
i.e., setting views that are not nested within the SearchView as not important
306+
for accessibility. These values are restored when the `SearchView` is hidden.
307+
308+
**Note** `SearchView` handles its siblings' accessibility by saving the original
309+
values when `SearchView` is shown, and restoring them when it's hidden. If
310+
changing the view hierarchy of the `SearchView`'s root view, make sure to call
311+
`setModalForAccessibility(false)` to restore the original a11y values. Eg. if
312+
removing the `SearchView` when open, you must call
313+
`setModalForAccessibility(false)` before removal to ensure that the original
314+
a11y values are restored since `SearchView.hide()` will never be called.
315+
304316
### Transition listeners
305317

306318
If you want to get callbacks for when the `SearchView` transitions between its

lib/java/com/google/android/material/search/SearchView.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import android.view.LayoutInflater;
4242
import android.view.View;
4343
import android.view.ViewGroup;
44+
import android.view.ViewTreeObserver.OnTouchModeChangeListener;
4445
import android.view.Window;
4546
import android.view.WindowManager;
4647
import android.view.accessibility.AccessibilityEvent;
@@ -171,6 +172,17 @@ public class SearchView extends FrameLayout
171172
private boolean statusBarSpacerEnabledOverride;
172173
@NonNull private TransitionState currentTransitionState = TransitionState.HIDDEN;
173174
private Map<View, Integer> childImportantForAccessibilityMap;
175+
private final OnTouchModeChangeListener touchModeChangeListener =
176+
new OnTouchModeChangeListener() {
177+
@Override
178+
public void onTouchModeChanged(boolean isInTouchMode) {
179+
// If we enter non touch mode and the SearchView is showing in the currently focused
180+
// window, request focus on the EditText to prevent focusing views behind SearchView.
181+
if (!isInTouchMode && hasWindowFocus() && isShowing() && editText != null) {
182+
editText.post(editText::requestFocus);
183+
}
184+
}
185+
};
174186

175187
public SearchView(@NonNull Context context) {
176188
this(context, null);
@@ -271,6 +283,7 @@ protected void onAttachedToWindow() {
271283
TransitionState state = getCurrentTransitionState();
272284
updateModalForAccessibility(state);
273285
updateListeningForBackCallbacks(state);
286+
getViewTreeObserver().addOnTouchModeChangeListener(touchModeChangeListener);
274287
}
275288

276289
@Override
@@ -279,6 +292,7 @@ protected void onDetachedFromWindow() {
279292

280293
setModalForAccessibility(/* isSearchViewModal= */ false);
281294
backOrchestrator.stopListeningForBackCallbacks();
295+
getViewTreeObserver().removeOnTouchModeChangeListener(touchModeChangeListener);
282296
}
283297

284298
@Override

lib/java/com/google/android/material/search/res/layout/mtrl_search_view.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
android:layout_height="match_parent"
3232
android:focusable="true"
3333
android:focusableInTouchMode="true"
34+
android:touchscreenBlocksFocus="true"
35+
android:keyboardNavigationCluster="true"
3436
android:visibility="gone">
3537

3638
<LinearLayout

0 commit comments

Comments
 (0)