Skip to content

Commit 14a7b40

Browse files
Material Design Teamafohrman
authored andcommitted
[AutoComplete] Enabled switch access in MaterialAutoCompleteTextView.
PiperOrigin-RevId: 587556416
1 parent 8ccec33 commit 14a7b40

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

lib/java/com/google/android/material/textfield/DropdownMenuEndIconDelegate.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ public void onPopulateAccessibilityEvent(View host, @NonNull AccessibilityEvent
240240
// TODO(b/256138189): Find better workaround, back gesture should call
241241
// AutoCompleteTextView.OnDismissListener.
242242
boolean invalidState =
243-
event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED
243+
(event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED
244+
|| event.getEventType() == AccessibilityEventCompat.CONTENT_CHANGE_TYPE_PANE_TITLE)
244245
&& isEndIconChecked
245246
&& !autoCompleteTextView.isPopupShowing();
246247
// If dropdown is non editable, layout click is what triggers showing/hiding the popup

lib/java/com/google/android/material/textfield/MaterialAutoCompleteTextView.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap;
2222

23+
import android.accessibilityservice.AccessibilityServiceInfo;
2324
import android.content.Context;
2425
import android.content.res.ColorStateList;
2526
import android.content.res.TypedArray;
@@ -35,6 +36,7 @@
3536
import android.text.InputType;
3637
import android.util.AttributeSet;
3738
import android.view.View;
39+
import android.view.View.MeasureSpec;
3840
import android.view.ViewGroup;
3941
import android.view.ViewGroup.LayoutParams;
4042
import android.view.ViewParent;
@@ -58,6 +60,7 @@
5860
import com.google.android.material.internal.ThemeEnforcement;
5961
import com.google.android.material.resources.MaterialResources;
6062
import com.google.android.material.shape.MaterialShapeDrawable;
63+
import java.util.List;
6164

6265
/**
6366
* A special sub-class of {@link android.widget.AutoCompleteTextView} that is auto-inflated so that
@@ -73,6 +76,7 @@
7376
public class MaterialAutoCompleteTextView extends AppCompatAutoCompleteTextView {
7477

7578
private static final int MAX_ITEMS_MEASURED = 15;
79+
private static final String SWITCH_ACCESS_ACTIVITY_NAME = "SwitchAccess";
7680

7781
@NonNull private final ListPopupWindow modalListPopup;
7882
@Nullable private final AccessibilityManager accessibilityManager;
@@ -185,7 +189,7 @@ public void onItemClick(AdapterView<?> parent, View selectedView, int position,
185189

186190
@Override
187191
public void showDropDown() {
188-
if (isTouchExplorationEnabled()) {
192+
if (isPopupRequired()) {
189193
modalListPopup.show();
190194
} else {
191195
super.showDropDown();
@@ -194,7 +198,7 @@ public void showDropDown() {
194198

195199
@Override
196200
public void dismissDropDown() {
197-
if (isTouchExplorationEnabled()) {
201+
if (isPopupRequired()) {
198202
modalListPopup.dismiss();
199203
} else {
200204
super.dismissDropDown();
@@ -203,18 +207,40 @@ public void dismissDropDown() {
203207

204208
@Override
205209
public void onWindowFocusChanged(boolean hasWindowFocus) {
206-
if (isTouchExplorationEnabled()) {
207-
// Do not dismissDropDown if touch exploration is enabled, in case the window lost focus
208-
// in favor of the modalListPopup.
210+
if (isPopupRequired()) {
211+
// Do not dismissDropDown if touch exploration or switch access is enabled, in case the window
212+
// lost focus in favor of the modalListPopup.
209213
return;
210214
}
211215
super.onWindowFocusChanged(hasWindowFocus);
212216
}
213217

218+
private boolean isPopupRequired() {
219+
return isTouchExplorationEnabled() || isSwitchAccessEnabled();
220+
}
221+
214222
private boolean isTouchExplorationEnabled() {
215223
return accessibilityManager != null && accessibilityManager.isTouchExplorationEnabled();
216224
}
217225

226+
private boolean isSwitchAccessEnabled() {
227+
if (accessibilityManager == null || !accessibilityManager.isEnabled()) {
228+
return false;
229+
}
230+
List<AccessibilityServiceInfo> accessibilityServiceInfos =
231+
accessibilityManager.getEnabledAccessibilityServiceList(
232+
AccessibilityServiceInfo.FEEDBACK_GENERIC);
233+
if (accessibilityServiceInfos != null) {
234+
for (AccessibilityServiceInfo info : accessibilityServiceInfos) {
235+
if (info.getSettingsActivityName() != null
236+
&& info.getSettingsActivityName().contains(SWITCH_ACCESS_ACTIVITY_NAME)) {
237+
return true;
238+
}
239+
}
240+
}
241+
return false;
242+
}
243+
218244
@Override
219245
public <T extends ListAdapter & Filterable> void setAdapter(@Nullable T adapter) {
220246
super.setAdapter(adapter);

0 commit comments

Comments
 (0)