|
41 | 41 | import android.view.LayoutInflater; |
42 | 42 | import android.view.View; |
43 | 43 | import android.view.ViewGroup; |
| 44 | +import android.view.accessibility.AccessibilityManager; |
44 | 45 | import android.view.accessibility.AccessibilityNodeInfo; |
45 | 46 | import android.widget.EditText; |
46 | 47 | import android.widget.ImageButton; |
|
57 | 58 | import androidx.core.graphics.drawable.DrawableCompat; |
58 | 59 | import androidx.core.view.MarginLayoutParamsCompat; |
59 | 60 | import androidx.core.view.ViewCompat; |
| 61 | +import androidx.core.view.accessibility.AccessibilityManagerCompat; |
| 62 | +import androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener; |
60 | 63 | import androidx.core.widget.TextViewCompat; |
61 | 64 | import androidx.customview.view.AbsSavedState; |
62 | 65 | import com.google.android.material.appbar.AppBarLayout; |
@@ -130,14 +133,17 @@ public class SearchBar extends Toolbar { |
130 | 133 | private final Drawable defaultNavigationIcon; |
131 | 134 | private final boolean tintNavigationIcon; |
132 | 135 | private final boolean forceDefaultNavigationOnClickListener; |
133 | | - |
134 | 136 | @Nullable private View centerView; |
135 | 137 | @Nullable private Integer navigationIconTint; |
136 | 138 | @Nullable private Drawable originalNavigationIconBackground; |
137 | 139 | private int menuResId = -1; |
138 | 140 | private boolean defaultScrollFlagsEnabled; |
139 | 141 | private MaterialShapeDrawable backgroundShape; |
140 | 142 |
|
| 143 | + @Nullable private final AccessibilityManager accessibilityManager; |
| 144 | + private final TouchExplorationStateChangeListener touchExplorationStateChangeListener = |
| 145 | + (boolean enabled) -> setFocusableInTouchMode(enabled); |
| 146 | + |
141 | 147 | public SearchBar(@NonNull Context context) { |
142 | 148 | this(context, null); |
143 | 149 | } |
@@ -194,6 +200,35 @@ public SearchBar(@NonNull Context context, @Nullable AttributeSet attrs, int def |
194 | 200 | ViewCompat.setElevation(this, elevation); |
195 | 201 | initTextView(textAppearanceResId, text, hint); |
196 | 202 | initBackground(shapeAppearanceModel, elevation, strokeWidth, strokeColor); |
| 203 | + |
| 204 | + accessibilityManager = |
| 205 | + (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); |
| 206 | + setupTouchExplorationStateChangeListener(); |
| 207 | + } |
| 208 | + |
| 209 | + private void setupTouchExplorationStateChangeListener() { |
| 210 | + if (accessibilityManager != null) { |
| 211 | + // Handle the case where touch exploration is already enabled. |
| 212 | + if (accessibilityManager.isEnabled() && accessibilityManager.isTouchExplorationEnabled()) { |
| 213 | + setFocusableInTouchMode(true); |
| 214 | + } |
| 215 | + |
| 216 | + // Handle the case where touch exploration state can change while the view is active. |
| 217 | + addOnAttachStateChangeListener( |
| 218 | + new OnAttachStateChangeListener() { |
| 219 | + @Override |
| 220 | + public void onViewAttachedToWindow(View ignored) { |
| 221 | + AccessibilityManagerCompat.addTouchExplorationStateChangeListener( |
| 222 | + accessibilityManager, touchExplorationStateChangeListener); |
| 223 | + } |
| 224 | + |
| 225 | + @Override |
| 226 | + public void onViewDetachedFromWindow(View ignored) { |
| 227 | + AccessibilityManagerCompat.removeTouchExplorationStateChangeListener( |
| 228 | + accessibilityManager, touchExplorationStateChangeListener); |
| 229 | + } |
| 230 | + }); |
| 231 | + } |
197 | 232 | } |
198 | 233 |
|
199 | 234 | private void validateAttributes(@Nullable AttributeSet attributeSet) { |
|
0 commit comments