Skip to content

Commit

Permalink
[CleanUp][TextField] Remove TextInputLayout.getEditText() calls from …
Browse files Browse the repository at this point in the history
…EndIconDelegates

PiperOrigin-RevId: 446240046
  • Loading branch information
drchen authored and leticiarossi committed May 3, 2022
1 parent 5549e53 commit 7b2f924
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 163 deletions.
Expand Up @@ -22,9 +22,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.EditText;
Expand All @@ -40,26 +38,24 @@ class ClearTextEndIconDelegate extends EndIconDelegate {
private static final int ANIMATION_SCALE_DURATION = 150;
private static final float ANIMATION_SCALE_FROM_VALUE = 0.8f;

@Nullable
private EditText editText;

private final OnClickListener onIconClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
Editable text = textInputLayout.getEditText().getText();
if (text != null) {
text.clear();
}

endLayout.refreshEndIconDrawableState();
private final OnClickListener onIconClickListener = view -> {
if (editText == null) {
return;
}
};

private final OnFocusChangeListener onFocusChangeListener = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
animateIcon(shouldBeVisible());
Editable text = editText.getText();
if (text != null) {
text.clear();
}

endLayout.refreshEndIconDrawableState();
};

private final OnFocusChangeListener onFocusChangeListener =
(view, hasFocus) -> animateIcon(shouldBeVisible());

private AnimatorSet iconInAnim;
private ValueAnimator iconOutAnim;

Expand All @@ -79,16 +75,10 @@ void setUp() {

@Override
void tearDown() {
final EditText editText = textInputLayout.getEditText();
if (editText != null) {
editText.post(
new Runnable() {
@Override
public void run() {
// Make sure icon view is visible.
animateIcon(/* show= */ true);
}
});
editText.post(() ->
// Make sure icon view is visible.
animateIcon(/* show= */ true));
}
}

Expand All @@ -107,6 +97,7 @@ OnClickListener getOnIconClickListener() {

@Override
public void onEditTextAttached(@Nullable EditText editText) {
this.editText = editText;
textInputLayout.setEndIconVisible(shouldBeVisible());
}

Expand Down Expand Up @@ -171,14 +162,10 @@ private ValueAnimator getAlphaAnimator(float... values) {
ValueAnimator animator = ValueAnimator.ofFloat(values);
animator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
animator.setDuration(ANIMATION_FADE_DURATION);
animator.addUpdateListener(
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(@NonNull ValueAnimator animation) {
float alpha = (float) animation.getAnimatedValue();
endIconView.setAlpha(alpha);
}
});
animator.addUpdateListener(animation -> {
float alpha = (float) animation.getAnimatedValue();
endIconView.setAlpha(alpha);
});

return animator;
}
Expand All @@ -187,20 +174,15 @@ private ValueAnimator getScaleAnimator() {
ValueAnimator animator = ValueAnimator.ofFloat(ANIMATION_SCALE_FROM_VALUE, 1);
animator.setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR);
animator.setDuration(ANIMATION_SCALE_DURATION);
animator.addUpdateListener(
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(@NonNull ValueAnimator animation) {
float scale = (float) animation.getAnimatedValue();
endIconView.setScaleX(scale);
endIconView.setScaleY(scale);
}
});
animator.addUpdateListener(animation -> {
float scale = (float) animation.getAnimatedValue();
endIconView.setScaleX(scale);
endIconView.setScaleY(scale);
});
return animator;
}

private boolean shouldBeVisible() {
EditText editText = textInputLayout.getEditText();
return editText != null
&& (editText.hasFocus() || endIconView.hasFocus())
&& editText.getText().length() > 0;
Expand Down
Expand Up @@ -26,7 +26,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build.VERSION;
Expand All @@ -36,12 +35,9 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
import android.widget.AutoCompleteTextView;
import android.widget.AutoCompleteTextView.OnDismissListener;
import android.widget.EditText;
import android.widget.Spinner;
import androidx.annotation.ChecksSdkIntAtLeast;
Expand All @@ -63,14 +59,17 @@ class DropdownMenuEndIconDelegate extends EndIconDelegate {
private static final int ANIMATION_FADE_OUT_DURATION = 50;
private static final int ANIMATION_FADE_IN_DURATION = 67;

@Nullable
private AutoCompleteTextView autoCompleteTextView;

private final TextInputLayout.AccessibilityDelegate accessibilityDelegate =
new AccessibilityDelegate(textInputLayout) {
@Override
public void onInitializeAccessibilityNodeInfo(
View host, @NonNull AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
// The non-editable exposed dropdown menu behaves like a Spinner.
if (!isEditable(textInputLayout.getEditText())) {
if (!isEditable(autoCompleteTextView)) {
info.setClassName(Spinner.class.getName());
}
if (info.isShowingHintText()) {
Expand All @@ -83,37 +82,24 @@ public void onInitializeAccessibilityNodeInfo(
@Override
public void onPopulateAccessibilityEvent(View host, @NonNull AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(host, event);
AutoCompleteTextView editText =
castAutoCompleteTextViewOrThrow(textInputLayout.getEditText());

// If dropdown is non editable, layout click is what triggers showing/hiding the popup
// list. Otherwise, arrow icon alone is what triggers it.
if (event.getEventType() == TYPE_VIEW_CLICKED
&& accessibilityManager.isEnabled()
&& !isEditable(textInputLayout.getEditText())) {
showHideDropdown(editText);
&& !isEditable(autoCompleteTextView)) {
showHideDropdown();
updateDropdownPopupDirty();
}
}
};

private final OnClickListener onIconClickListener = view -> showHideDropdown();

private final OnClickListener onIconClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
AutoCompleteTextView editText = (AutoCompleteTextView) textInputLayout.getEditText();
showHideDropdown(editText);
}
};

private final OnFocusChangeListener onEditTextFocusChangeListener = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
endLayout.setEndIconActivated(hasFocus);
if (!hasFocus) {
setEndIconChecked(false);
dropdownPopupDirty = false;
}
private final OnFocusChangeListener onEditTextFocusChangeListener = (view, hasFocus) -> {
endLayout.setEndIconActivated(hasFocus);
if (!hasFocus) {
setEndIconChecked(false);
dropdownPopupDirty = false;
}
};

Expand Down Expand Up @@ -144,31 +130,25 @@ void setUp() {
accessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
accessibilityManager.addTouchExplorationStateChangeListener(
new TouchExplorationStateChangeListener() {
@Override
public void onTouchExplorationStateChanged(boolean enabled) {
if (textInputLayout.getEditText() != null
&& !isEditable(textInputLayout.getEditText())) {
ViewCompat.setImportantForAccessibility(
endIconView,
enabled ? IMPORTANT_FOR_ACCESSIBILITY_NO : IMPORTANT_FOR_ACCESSIBILITY_YES);
}
}
});
accessibilityManager.addTouchExplorationStateChangeListener(enabled -> {
if (autoCompleteTextView != null && !isEditable(autoCompleteTextView)) {
ViewCompat.setImportantForAccessibility(
endIconView,
enabled ? IMPORTANT_FOR_ACCESSIBILITY_NO : IMPORTANT_FOR_ACCESSIBILITY_YES);
}
});
}
}

@SuppressLint("ClickableViewAccessibility") // There's an accessibility delegate that handles
// interactions with the dropdown menu.
@Override
void tearDown() {
final AutoCompleteTextView editText = (AutoCompleteTextView) textInputLayout.getEditText();
if (editText != null) {
if (autoCompleteTextView != null) {
// Remove any listeners set on the edit text.
editText.setOnTouchListener(null);
autoCompleteTextView.setOnTouchListener(null);
if (IS_LOLLIPOP) {
editText.setOnDismissListener(null);
autoCompleteTextView.setOnDismissListener(null);
}
}
}
Expand All @@ -190,12 +170,11 @@ OnClickListener getOnIconClickListener() {

@Override
public void onEditTextAttached(@Nullable EditText editText) {
AutoCompleteTextView autoCompleteTextView = castAutoCompleteTextViewOrThrow(editText);
setUpDropdownShowHideBehavior(autoCompleteTextView);
autoCompleteTextView.setThreshold(0);
this.autoCompleteTextView = castAutoCompleteTextViewOrThrow(editText);
setUpDropdownShowHideBehavior();
textInputLayout.setEndIconCheckable(true);
textInputLayout.setErrorIconDrawable(null);
if (!isEditable(autoCompleteTextView) && accessibilityManager.isTouchExplorationEnabled()) {
if (!isEditable(editText) && accessibilityManager.isTouchExplorationEnabled()) {
ViewCompat.setImportantForAccessibility(endIconView, IMPORTANT_FOR_ACCESSIBILITY_NO);
}
textInputLayout.setTextInputAccessibilityDelegate(accessibilityDelegate);
Expand All @@ -205,32 +184,26 @@ public void onEditTextAttached(@Nullable EditText editText) {

@Override
public void afterEditTextChanged(Editable s) {
final AutoCompleteTextView editText =
castAutoCompleteTextViewOrThrow(textInputLayout.getEditText());
// Don't show dropdown list if we're in a11y mode and the menu is editable.
if (accessibilityManager.isTouchExplorationEnabled()
&& isEditable(editText)
&& isEditable(autoCompleteTextView)
&& !endIconView.hasFocus()) {
editText.dismissDropDown();
autoCompleteTextView.dismissDropDown();
}
editText.post(
new Runnable() {
@Override
public void run() {
boolean isPopupShowing = editText.isPopupShowing();
setEndIconChecked(isPopupShowing);
dropdownPopupDirty = isPopupShowing;
}
});
autoCompleteTextView.post(() -> {
boolean isPopupShowing = autoCompleteTextView.isPopupShowing();
setEndIconChecked(isPopupShowing);
dropdownPopupDirty = isPopupShowing;
});
}

@Override
OnFocusChangeListener getOnEditTextFocusChangeListener() {
return onEditTextFocusChangeListener;
}

private void showHideDropdown(@Nullable AutoCompleteTextView editText) {
if (editText == null) {
private void showHideDropdown() {
if (autoCompleteTextView == null) {
return;
}
if (isDropdownPopupActive()) {
Expand All @@ -244,10 +217,10 @@ private void showHideDropdown(@Nullable AutoCompleteTextView editText) {
endIconView.toggle();
}
if (isEndIconChecked) {
editText.requestFocus();
editText.showDropDown();
autoCompleteTextView.requestFocus();
autoCompleteTextView.showDropDown();
} else {
editText.dismissDropDown();
autoCompleteTextView.dismissDropDown();
}
} else {
dropdownPopupDirty = false;
Expand All @@ -256,32 +229,25 @@ private void showHideDropdown(@Nullable AutoCompleteTextView editText) {

@SuppressLint("ClickableViewAccessibility") // There's an accessibility delegate that handles
// interactions with the dropdown menu.
private void setUpDropdownShowHideBehavior(@NonNull final AutoCompleteTextView editText) {
private void setUpDropdownShowHideBehavior() {
// Set whole layout clickable.
editText.setOnTouchListener(
new OnTouchListener() {
@Override
public boolean onTouch(@NonNull View v, @NonNull MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (isDropdownPopupActive()) {
dropdownPopupDirty = false;
}
showHideDropdown(editText);
updateDropdownPopupDirty();
}
return false;
}
});
autoCompleteTextView.setOnTouchListener((view, event) -> {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (isDropdownPopupActive()) {
dropdownPopupDirty = false;
}
showHideDropdown();
updateDropdownPopupDirty();
}
return false;
});
if (IS_LOLLIPOP) {
editText.setOnDismissListener(
new OnDismissListener() {
@Override
public void onDismiss() {
updateDropdownPopupDirty();
setEndIconChecked(false);
}
});
autoCompleteTextView.setOnDismissListener(() -> {
updateDropdownPopupDirty();
setEndIconChecked(false);
});
}
autoCompleteTextView.setThreshold(0);
}

private boolean isDropdownPopupActive() {
Expand Down Expand Up @@ -330,14 +296,10 @@ private ValueAnimator getAlphaAnimator(int duration, float... values) {
ValueAnimator animator = ValueAnimator.ofFloat(values);
animator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
animator.setDuration(duration);
animator.addUpdateListener(
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(@NonNull ValueAnimator animation) {
float alpha = (float) animation.getAnimatedValue();
endIconView.setAlpha(alpha);
}
});
animator.addUpdateListener(animation -> {
float alpha = (float) animation.getAnimatedValue();
endIconView.setAlpha(alpha);
});

return animator;
}
Expand Down

0 comments on commit 7b2f924

Please sign in to comment.