diff --git a/lib/res/values/dimens.xml b/lib/res/values/dimens.xml index 2343a7edd..64e159ab1 100644 --- a/lib/res/values/dimens.xml +++ b/lib/res/values/dimens.xml @@ -36,6 +36,8 @@ 14sp 12sp + 5dp + -1px -1px 6dp diff --git a/lib/src/android/support/design/widget/TextInputLayout.java b/lib/src/android/support/design/widget/TextInputLayout.java index 3792c4b00..1387524c2 100644 --- a/lib/src/android/support/design/widget/TextInputLayout.java +++ b/lib/src/android/support/design/widget/TextInputLayout.java @@ -18,6 +18,8 @@ package android.support.design.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.ColorStateList; @@ -110,17 +112,26 @@ import android.widget.TextView; */ public class TextInputLayout extends LinearLayout { - private static final int ANIMATION_DURATION = 200; // Duration for the label's scale up and down animations. private static final int LABEL_SCALE_ANIMATION_DURATION = 167; + // Duration for the error text's vertical translation animation. + private static final int ERROR_TRANSLATE_Y_ANIMATION_DURATION = 250; + + // Durations for the error text's opacity fade animations. + private static final int ERROR_OPACITY_FADE_IN_ANIMATION_DURATION = 167; + private static final int ERROR_OPACITY_FADE_OUT_ANIMATION_DURATION = 83; + private static final int INVALID_MAX_LENGTH = -1; private static final String LOG_TAG = "TextInputLayout"; private final FrameLayout mInputFrame; + private @Nullable Animator mErrorAnimator; EditText mEditText; + private final float mErrorTextTranslationYPx; + private boolean mHintEnabled; private CharSequence mHint; @@ -259,6 +270,9 @@ public class TextInputLayout extends LinearLayout { } ViewCompat.setAccessibilityDelegate(this, new TextInputAccessibilityDelegate()); + + mErrorTextTranslationYPx = + getResources().getDimensionPixelSize(R.dimen.design_textinput_error_translate_y); } @Override @@ -597,6 +611,9 @@ public class TextInputLayout extends LinearLayout { if (mErrorEnabled != enabled) { if (mErrorView != null) { mErrorView.animate().cancel(); + if (mErrorAnimator != null) { + mErrorAnimator.cancel(); + } } if (enabled) { @@ -700,6 +717,9 @@ public class TextInputLayout extends LinearLayout { // Cancel any on-going animation mErrorView.animate().cancel(); + if (mErrorAnimator != null) { + mErrorAnimator.cancel(); + } if (mErrorShown) { mErrorView.setText(error); @@ -710,19 +730,35 @@ public class TextInputLayout extends LinearLayout { // If it's currently 100% show, we'll animate it from 0 mErrorView.setAlpha(0f); } - mErrorView - .animate() - .alpha(1f) - .setDuration(ANIMATION_DURATION) - .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR) - .setListener( - new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - mErrorView.setVisibility(VISIBLE); - } - }) - .start(); + + ObjectAnimator errorOpacityAnimator = ObjectAnimator.ofFloat(mErrorView, ALPHA, 1f); + ObjectAnimator errorTranslationYAnimator = + ObjectAnimator.ofFloat(mErrorView, TRANSLATION_Y, -mErrorTextTranslationYPx, 0); + + errorOpacityAnimator + .setDuration(ERROR_OPACITY_FADE_IN_ANIMATION_DURATION) + .setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR); + errorTranslationYAnimator + .setDuration(ERROR_TRANSLATE_Y_ANIMATION_DURATION) + .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR); + + final AnimatorSet errorAnimatorSet = new AnimatorSet(); + mErrorAnimator = errorAnimatorSet; + + errorAnimatorSet.playTogether(errorOpacityAnimator, errorTranslationYAnimator); + errorAnimatorSet.addListener( + new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mErrorAnimator = null; + } + + @Override + public void onAnimationStart(Animator animation) { + mErrorView.setVisibility(VISIBLE); + } + }); + errorAnimatorSet.start(); } else { // Set alpha to 1f, just in case mErrorView.setAlpha(1f); @@ -733,8 +769,8 @@ public class TextInputLayout extends LinearLayout { mErrorView .animate() .alpha(0f) - .setDuration(ANIMATION_DURATION) - .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR) + .setDuration(ERROR_OPACITY_FADE_OUT_ANIMATION_DURATION) + .setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR) .setListener( new AnimatorListenerAdapter() { @Override @@ -750,7 +786,6 @@ public class TextInputLayout extends LinearLayout { } } } - updateEditTextBackground(); updateLabelState(animate); }