Skip to content

Commit

Permalink
[TextInputLayout] Update motion attributes for textfield animations
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 472525831
  • Loading branch information
imhappi authored and afohrman committed Sep 8, 2022
1 parent 347cb9e commit c98480c
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.text.Editable;
import android.view.View.OnClickListener;
Expand All @@ -29,13 +30,18 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.animation.AnimationUtils;
import com.google.android.material.motion.MotionUtils;

/** Default initialization of the clear text end icon {@link TextInputLayout.EndIconMode}. */
class ClearTextEndIconDelegate extends EndIconDelegate {

private static final int ANIMATION_FADE_DURATION = 100;
private static final int ANIMATION_SCALE_DURATION = 150;
private static final int DEFAULT_ANIMATION_FADE_DURATION = 100;
private static final int DEFAULT_ANIMATION_SCALE_DURATION = 150;
private static final float ANIMATION_SCALE_FROM_VALUE = 0.8f;
private final int animationFadeDuration;
private final int animationScaleDuration;
@NonNull private final TimeInterpolator animationFadeInterpolator;
@NonNull private final TimeInterpolator animationScaleInterpolator;

@Nullable
private EditText editText;
Expand All @@ -59,6 +65,22 @@ class ClearTextEndIconDelegate extends EndIconDelegate {

ClearTextEndIconDelegate(@NonNull EndCompoundLayout endLayout) {
super(endLayout);
animationFadeDuration =
MotionUtils.resolveThemeDuration(
endLayout.getContext(), R.attr.motionDurationShort3, DEFAULT_ANIMATION_FADE_DURATION);
animationScaleDuration =
MotionUtils.resolveThemeDuration(
endLayout.getContext(), R.attr.motionDurationShort3, DEFAULT_ANIMATION_SCALE_DURATION);
animationFadeInterpolator =
MotionUtils.resolveThemeInterpolator(
endLayout.getContext(),
R.attr.motionEasingLinearInterpolator,
AnimationUtils.LINEAR_INTERPOLATOR);
animationScaleInterpolator =
MotionUtils.resolveThemeInterpolator(
endLayout.getContext(),
R.attr.motionEasingEmphasizedInterpolator,
AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR);
}

@Override
Expand Down Expand Up @@ -163,8 +185,8 @@ public void onAnimationEnd(Animator animation) {

private ValueAnimator getAlphaAnimator(float... values) {
ValueAnimator animator = ValueAnimator.ofFloat(values);
animator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
animator.setDuration(ANIMATION_FADE_DURATION);
animator.setInterpolator(animationFadeInterpolator);
animator.setDuration(animationFadeDuration);
animator.addUpdateListener(animation -> {
float alpha = (float) animation.getAnimatedValue();
endIconView.setAlpha(alpha);
Expand All @@ -175,8 +197,8 @@ private ValueAnimator getAlphaAnimator(float... values) {

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.setInterpolator(animationScaleInterpolator);
animator.setDuration(animationScaleDuration);
animator.addUpdateListener(animation -> {
float scale = (float) animation.getAnimatedValue();
endIconView.setScaleX(scale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
Expand All @@ -47,6 +48,7 @@
import androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import com.google.android.material.animation.AnimationUtils;
import com.google.android.material.motion.MotionUtils;
import com.google.android.material.textfield.TextInputLayout.BoxBackgroundMode;

/** Default initialization of the exposed dropdown menu {@link TextInputLayout.EndIconMode}. */
Expand All @@ -55,8 +57,11 @@ class DropdownMenuEndIconDelegate extends EndIconDelegate {
@ChecksSdkIntAtLeast(api = VERSION_CODES.LOLLIPOP)
private static final boolean IS_LOLLIPOP = VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP;

private static final int ANIMATION_FADE_OUT_DURATION = 50;
private static final int ANIMATION_FADE_IN_DURATION = 67;
private static final int DEFAULT_ANIMATION_FADE_OUT_DURATION = 50;
private static final int DEFAULT_ANIMATION_FADE_IN_DURATION = 67;
private final int animationFadeOutDuration;
private final int animationFadeInDuration;
@NonNull private final TimeInterpolator animationFadeInterpolator;

@Nullable
private AutoCompleteTextView autoCompleteTextView;
Expand Down Expand Up @@ -91,6 +96,21 @@ class DropdownMenuEndIconDelegate extends EndIconDelegate {

DropdownMenuEndIconDelegate(@NonNull EndCompoundLayout endLayout) {
super(endLayout);
animationFadeInDuration =
MotionUtils.resolveThemeDuration(
endLayout.getContext(),
R.attr.motionDurationShort3,
DEFAULT_ANIMATION_FADE_IN_DURATION);
animationFadeOutDuration =
MotionUtils.resolveThemeDuration(
endLayout.getContext(),
R.attr.motionDurationShort3,
DEFAULT_ANIMATION_FADE_OUT_DURATION);
animationFadeInterpolator =
MotionUtils.resolveThemeInterpolator(
endLayout.getContext(),
R.attr.motionEasingLinearInterpolator,
AnimationUtils.LINEAR_INTERPOLATOR);
}

@Override
Expand Down Expand Up @@ -300,8 +320,8 @@ private void setEndIconChecked(boolean checked) {
}

private void initAnimators() {
fadeInAnim = getAlphaAnimator(ANIMATION_FADE_IN_DURATION, 0, 1);
fadeOutAnim = getAlphaAnimator(ANIMATION_FADE_OUT_DURATION, 1, 0);
fadeInAnim = getAlphaAnimator(animationFadeInDuration, 0, 1);
fadeOutAnim = getAlphaAnimator(animationFadeOutDuration, 1, 0);
fadeOutAnim.addListener(
new AnimatorListenerAdapter() {
@Override
Expand All @@ -314,7 +334,7 @@ public void onAnimationEnd(Animator animation) {

private ValueAnimator getAlphaAnimator(int duration, float... values) {
ValueAnimator animator = ValueAnimator.ofFloat(values);
animator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
animator.setInterpolator(animationFadeInterpolator);
animator.setDuration(duration);
animator.addUpdateListener(animation -> {
float alpha = (float) animation.getAnimatedValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
Expand All @@ -51,6 +52,7 @@
import androidx.core.widget.TextViewCompat;
import com.google.android.material.animation.AnimationUtils;
import com.google.android.material.animation.AnimatorSetCompat;
import com.google.android.material.motion.MotionUtils;
import com.google.android.material.resources.MaterialResources;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand All @@ -65,10 +67,17 @@
final class IndicatorViewController {

/** Duration for the caption's vertical translation animation. */
private static final int CAPTION_TRANSLATE_Y_ANIMATION_DURATION = 217;
private static final int DEFAULT_CAPTION_TRANSLATION_Y_ANIMATION_DURATION = 217;

/** Duration for the caption's opacity fade animation. */
private static final int CAPTION_OPACITY_FADE_ANIMATION_DURATION = 167;
/** Duration for the caption's fade animation. */
private static final int DEFAULT_CAPTION_FADE_ANIMATION_DURATION = 167;

private final int captionTranslationYAnimationDuration;
private final int captionFadeInAnimationDuration;
private final int captionFadeOutAnimationDuration;
@NonNull private final TimeInterpolator captionTranslationYAnimationInterpolator;
@NonNull private final TimeInterpolator captionFadeInAnimationInterpolator;
@NonNull private final TimeInterpolator captionFadeOutAnimationInterpolator;

/**
* Values for indicator indices. Indicators are views below the text input area, like a caption
Expand Down Expand Up @@ -126,6 +135,28 @@ public IndicatorViewController(@NonNull TextInputLayout textInputView) {
this.textInputView = textInputView;
this.captionTranslationYPx =
context.getResources().getDimensionPixelSize(R.dimen.design_textinput_caption_translate_y);
captionTranslationYAnimationDuration =
MotionUtils.resolveThemeDuration(
context, R.attr.motionDurationShort4, DEFAULT_CAPTION_TRANSLATION_Y_ANIMATION_DURATION);
captionFadeInAnimationDuration =
MotionUtils.resolveThemeDuration(
context, R.attr.motionDurationMedium4, DEFAULT_CAPTION_FADE_ANIMATION_DURATION);
captionFadeOutAnimationDuration =
MotionUtils.resolveThemeDuration(
context, R.attr.motionDurationShort4, DEFAULT_CAPTION_FADE_ANIMATION_DURATION);
captionTranslationYAnimationInterpolator =
MotionUtils.resolveThemeInterpolator(
context,
R.attr.motionEasingEmphasizedDecelerateInterpolator,
AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR);
captionFadeInAnimationInterpolator =
MotionUtils.resolveThemeInterpolator(
context,
R.attr.motionEasingEmphasizedDecelerateInterpolator,
AnimationUtils.LINEAR_INTERPOLATOR);
captionFadeOutAnimationInterpolator =
MotionUtils.resolveThemeInterpolator(
context, R.attr.motionEasingLinearInterpolator, AnimationUtils.LINEAR_INTERPOLATOR);
}

void showHelper(final CharSequence helperText) {
Expand Down Expand Up @@ -319,16 +350,18 @@ private void createCaptionAnimators(
private ObjectAnimator createCaptionOpacityAnimator(TextView captionView, boolean display) {
float endValue = display ? 1f : 0f;
ObjectAnimator opacityAnimator = ObjectAnimator.ofFloat(captionView, View.ALPHA, endValue);
opacityAnimator.setDuration(CAPTION_OPACITY_FADE_ANIMATION_DURATION);
opacityAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
opacityAnimator.setDuration(display ? captionFadeInAnimationDuration
: captionFadeOutAnimationDuration);
opacityAnimator.setInterpolator(display ? captionFadeInAnimationInterpolator
: captionFadeOutAnimationInterpolator);
return opacityAnimator;
}

private ObjectAnimator createCaptionTranslationYAnimator(TextView captionView) {
ObjectAnimator translationYAnimator =
ObjectAnimator.ofFloat(captionView, TRANSLATION_Y, -captionTranslationYPx, 0f);
translationYAnimator.setDuration(CAPTION_TRANSLATE_Y_ANIMATION_DURATION);
translationYAnimator.setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR);
translationYAnimator.setDuration(captionTranslationYAnimationDuration);
translationYAnimator.setInterpolator(captionTranslationYAnimationInterpolator);
return translationYAnimator;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ public class TextInputLayout extends LinearLayout {
/** Duration for the label's scale up and down animations. */
private static final int LABEL_SCALE_ANIMATION_DURATION = 167;

private static final long PLACEHOLDER_FADE_DURATION = 87;
private static final long PLACEHOLDER_START_DELAY = 67;
private static final int DEFAULT_PLACEHOLDER_FADE_DURATION = 87;
private static final int PLACEHOLDER_START_DELAY = 67;

private static final int INVALID_MAX_LENGTH = -1;
private static final int NO_WIDTH = -1;
Expand Down Expand Up @@ -2406,8 +2406,10 @@ private void setPlaceholderTextEnabled(boolean placeholderEnabled) {

private Fade createPlaceholderFadeTransition() {
Fade placeholderFadeTransition = new Fade();
placeholderFadeTransition.setDuration(PLACEHOLDER_FADE_DURATION);
placeholderFadeTransition.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
placeholderFadeTransition.setDuration(MotionUtils.resolveThemeDuration(getContext(),
R.attr.motionDurationShort2, DEFAULT_PLACEHOLDER_FADE_DURATION));
placeholderFadeTransition.setInterpolator(MotionUtils.resolveThemeInterpolator(getContext(),
R.attr.motionEasingLinearInterpolator, AnimationUtils.LINEAR_INTERPOLATOR));
return placeholderFadeTransition;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2016 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="NewApi">

<aapt:attr name="android:drawable">

<vector
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">

<path
android:name="strike_through"
android:pathData="@string/path_password_strike_through"
android:strokeColor="@android:color/white"
android:strokeLineCap="square"
android:strokeWidth="1.8"
android:trimPathEnd="0"/>

<group>

<clip-path
android:name="eye_mask"
android:pathData="@string/path_password_eye_mask_visible"/>

<path
android:fillColor="@android:color/white"
android:name="eye"
android:pathData="@string/path_password_eye"/>

</group>

</vector>

</aapt:attr>

<target android:name="eye_mask">

<aapt:attr name="android:animation">

<objectAnimator
android:duration="?attr/motionDurationMedium2"
android:interpolator="?attr/motionEasingStandardInterpolator"
android:propertyName="pathData"
android:valueFrom="@string/path_password_eye_mask_visible"
android:valueTo="@string/path_password_eye_mask_strike_through"
android:valueType="pathType"/>

</aapt:attr>

</target>

<target android:name="strike_through">

<aapt:attr name="android:animation">

<objectAnimator
android:duration="?attr/motionDurationMedium2"
android:interpolator="?attr/motionEasingStandardInterpolator"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"/>

</aapt:attr>

</target>

</animated-vector>
Loading

0 comments on commit c98480c

Please sign in to comment.