Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2af2705b authored by Ahaan Ugale's avatar Ahaan Ugale Committed by Automerger Merge Worker
Browse files

Merge changes from topic "tr-anim" into sc-dev am: 27008c11 am: 565c15a8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14661091

Change-Id: Ibcfc48257be24c2c7e7ea287a01c5a3bae3ced19
parents 86163fc0 565c15a8
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -404,9 +404,6 @@ public class UiTranslationController {
                            // implememtation.
                            callback = new TextViewTranslationCallback();
                            view.setViewTranslationCallback(callback);
                            if (mViewsToPadContent.contains(autofillId)) {
                                callback.enableContentPadding();
                            }
                        } else {
                            if (DEBUG) {
                                Log.d(TAG, view + " doesn't support showing translation because of "
@@ -415,6 +412,10 @@ public class UiTranslationController {
                            return;
                        }
                    }
                    callback.setAnimationDurationMillis(ANIMATION_DURATION_MILLIS);
                    if (mViewsToPadContent.contains(autofillId)) {
                        callback.enableContentPadding();
                    }
                    view.onViewTranslationResponse(response);
                    callback.onShowTranslation(view);
                });
@@ -422,6 +423,9 @@ public class UiTranslationController {
        }
    }

    // TODO: Use a device config value.
    private static final int ANIMATION_DURATION_MILLIS = 250;

    /**
     * Creates a Translator for the given source and target translation specs and start the ui
     * translation when the Translator is created successfully.
+8 −0
Original line number Diff line number Diff line
@@ -64,4 +64,12 @@ public interface ViewTranslationCallback {
     * @hide
     */
    default void enableContentPadding() {}

    /**
     * Sets the duration for animations while transitioning the view between the original and
     * translated contents.
     *
     * @hide
     */
    default void setAnimationDurationMillis(int durationMillis) {}
}
+81 −5
Original line number Diff line number Diff line
@@ -16,10 +16,15 @@

package android.widget;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Build;
import android.text.TextUtils;
import android.text.method.TransformationMethod;
import android.text.method.TranslationTransformationMethod;
import android.util.Log;
import android.view.View;
@@ -47,6 +52,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
    private boolean mIsShowingTranslation = false;
    private boolean mIsTextPaddingEnabled = false;
    private CharSequence mPaddedText;
    private int mAnimationDurationMillis = 250; // default value

    private CharSequence mContentDescription;

@@ -82,14 +88,19 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
     */
    @Override
    public boolean onShowTranslation(@NonNull View view) {
        mIsShowingTranslation = true;
        if (view.getViewTranslationResponse() == null) {
            Log.wtf(TAG, "onShowTranslation() shouldn't be called before "
                    + "onViewTranslationResponse().");
            return false;
        }
        if (mTranslationTransformation != null) {
            ((TextView) view).setTransformationMethod(mTranslationTransformation);
            final TransformationMethod transformation = mTranslationTransformation;
            runWithAnimation(
                    (TextView) view,
                    () -> {
                        mIsShowingTranslation = true;
                        ((TextView) view).setTransformationMethod(transformation);
                    });
            ViewTranslationResponse response = view.getViewTranslationResponse();
            if (response.getKeys().contains(ViewTranslationRequest.ID_CONTENT_DESCRIPTION)) {
                CharSequence translatedContentDescription =
@@ -114,7 +125,6 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
     */
    @Override
    public boolean onHideTranslation(@NonNull View view) {
        mIsShowingTranslation = false;
        if (view.getViewTranslationResponse() == null) {
            Log.wtf(TAG, "onHideTranslation() shouldn't be called before "
                    + "onViewTranslationResponse().");
@@ -122,8 +132,14 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
        }
        // Restore to original text content.
        if (mTranslationTransformation != null) {
            ((TextView) view).setTransformationMethod(
                    mTranslationTransformation.getOriginalTransformationMethod());
            final TransformationMethod transformation =
                    mTranslationTransformation.getOriginalTransformationMethod();
            runWithAnimation(
                    (TextView) view,
                    () -> {
                        mIsShowingTranslation = false;
                        ((TextView) view).setTransformationMethod(transformation);
                    });
            if (!TextUtils.isEmpty(mContentDescription)) {
                view.setContentDescription(mContentDescription);
            }
@@ -212,4 +228,64 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
    }

    private static final char COMPAT_PAD_CHARACTER = '\u2002';

    @Override
    public void setAnimationDurationMillis(int durationMillis) {
        mAnimationDurationMillis = durationMillis;
    }

    /**
     * Applies a simple text alpha animation when toggling between original and translated text. The
     * text is fully faded out, then swapped to the new text, then the fading is reversed.
     *
     * @param runnable the operation to run on the view after the text is faded out, to change to
     * displaying the original or translated text.
     */
    private void runWithAnimation(TextView view, Runnable runnable) {
        if (mAnimator != null) {
            mAnimator.end();
            // Note: mAnimator is now null; do not use again here.
        }
        int fadedOutColor = colorWithAlpha(view.getCurrentTextColor(), 0);
        mAnimator = ValueAnimator.ofArgb(view.getCurrentTextColor(), fadedOutColor);
        mAnimator.addUpdateListener(
                // Note that if the text has a ColorStateList, this replaces it with a single color
                // for all states. The original ColorStateList is restored when the animation ends
                // (see below).
                (valueAnimator) -> view.setTextColor((Integer) valueAnimator.getAnimatedValue()));
        mAnimator.setRepeatMode(ValueAnimator.REVERSE);
        mAnimator.setRepeatCount(1);
        mAnimator.setDuration(mAnimationDurationMillis);
        final ColorStateList originalColors = view.getTextColors();
        mAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                view.setTextColor(originalColors);
                mAnimator = null;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                runnable.run();
            }
        });
        mAnimator.start();
    }

    private ValueAnimator mAnimator;

    /**
     * Returns {@code color} with alpha changed to {@code newAlpha}
     */
    private static int colorWithAlpha(int color, int newAlpha) {
        return Color.argb(newAlpha, Color.red(color), Color.green(color), Color.blue(color));
    }
}