Skip to content

Commit 948d5da

Browse files
authored
[TextInputLayout] Fix for TextInputLayout leak via AccessibilityManager. (#2718)
[TextInputLayout] Fix for TextInputLayout leak via AccessibilityManager. Adaptation of 673cefc for 1.6 Resolves #2615
1 parent 768d0cf commit 948d5da

File tree

1 file changed

+53
-15
lines changed

1 file changed

+53
-15
lines changed

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

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@
4040
import android.text.TextWatcher;
4141
import android.view.MotionEvent;
4242
import android.view.View;
43+
import android.view.View.OnAttachStateChangeListener;
4344
import android.view.View.OnClickListener;
4445
import android.view.View.OnFocusChangeListener;
4546
import android.view.View.OnTouchListener;
4647
import android.view.accessibility.AccessibilityEvent;
4748
import android.view.accessibility.AccessibilityManager;
48-
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
4949
import android.widget.AutoCompleteTextView;
5050
import android.widget.AutoCompleteTextView.OnDismissListener;
5151
import android.widget.EditText;
@@ -54,6 +54,8 @@
5454
import androidx.annotation.NonNull;
5555
import androidx.annotation.Nullable;
5656
import androidx.core.view.ViewCompat;
57+
import androidx.core.view.accessibility.AccessibilityManagerCompat;
58+
import androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener;
5759
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
5860
import com.google.android.material.animation.AnimationUtils;
5961
import com.google.android.material.color.MaterialColors;
@@ -190,6 +192,38 @@ public void run() {
190192
editText.setOnDismissListener(null);
191193
}
192194
}
195+
if (previousIcon == TextInputLayout.END_ICON_DROPDOWN_MENU) {
196+
textInputLayout.removeOnAttachStateChangeListener(onAttachStateChangeListener);
197+
removeTouchExplorationStateChangeListenerIfNeeded();
198+
}
199+
}
200+
};
201+
202+
private final OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener() {
203+
@Override
204+
public void onViewAttachedToWindow(View ignored) {
205+
addTouchExplorationStateChangeListenerIfNeeded();
206+
}
207+
208+
@Override
209+
public void onViewDetachedFromWindow(View ignored) {
210+
removeTouchExplorationStateChangeListenerIfNeeded();
211+
}
212+
};
213+
214+
private final TouchExplorationStateChangeListener touchExplorationStateChangeListener =
215+
new TouchExplorationStateChangeListener() {
216+
@Override
217+
public void onTouchExplorationStateChanged(boolean enabled) {
218+
if (textInputLayout != null) {
219+
final AutoCompleteTextView autoCompleteTextView =
220+
(AutoCompleteTextView) textInputLayout.getEditText();
221+
if (autoCompleteTextView != null && !isEditable(autoCompleteTextView)) {
222+
ViewCompat.setImportantForAccessibility(
223+
endIconView,
224+
enabled ? IMPORTANT_FOR_ACCESSIBILITY_NO : IMPORTANT_FOR_ACCESSIBILITY_YES);
225+
}
226+
}
193227
}
194228
};
195229

@@ -265,20 +299,8 @@ public void onClick(View v) {
265299
initAnimators();
266300
accessibilityManager =
267301
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
268-
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
269-
accessibilityManager.addTouchExplorationStateChangeListener(
270-
new TouchExplorationStateChangeListener() {
271-
@Override
272-
public void onTouchExplorationStateChanged(boolean enabled) {
273-
if (textInputLayout.getEditText() != null
274-
&& !isEditable(textInputLayout.getEditText())) {
275-
ViewCompat.setImportantForAccessibility(
276-
endIconView,
277-
enabled ? IMPORTANT_FOR_ACCESSIBILITY_NO : IMPORTANT_FOR_ACCESSIBILITY_YES);
278-
}
279-
}
280-
});
281-
}
302+
textInputLayout.addOnAttachStateChangeListener(onAttachStateChangeListener);
303+
addTouchExplorationStateChangeListenerIfNeeded();
282304
}
283305

284306
@Override
@@ -530,4 +552,20 @@ public void onAnimationUpdate(@NonNull ValueAnimator animation) {
530552

531553
return animator;
532554
}
555+
556+
private void addTouchExplorationStateChangeListenerIfNeeded() {
557+
if (accessibilityManager != null
558+
&& textInputLayout != null
559+
&& ViewCompat.isAttachedToWindow(textInputLayout)) {
560+
AccessibilityManagerCompat.addTouchExplorationStateChangeListener(
561+
accessibilityManager, touchExplorationStateChangeListener);
562+
}
563+
}
564+
565+
private void removeTouchExplorationStateChangeListenerIfNeeded() {
566+
if (accessibilityManager != null) {
567+
AccessibilityManagerCompat.removeTouchExplorationStateChangeListener(
568+
accessibilityManager, touchExplorationStateChangeListener);
569+
}
570+
}
533571
}

0 commit comments

Comments
 (0)