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

Commit 8f7d3715 authored by George Mount's avatar George Mount Committed by Android (Google) Code Review
Browse files

Merge "Allow PathMotion to affect translations in ChangeTransform." into lmp-mr1-dev

parents 9cb3c000 fa35d14e
Loading
Loading
Loading
Loading
+90 −11
Original line number Diff line number Diff line
@@ -17,11 +17,14 @@ package android.transition;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.FloatArrayEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Property;
import android.view.GhostView;
@@ -56,16 +59,35 @@ public class ChangeTransform extends Transition {
            PROPNAME_PARENT_MATRIX,
    };

    private static final Property<View, Matrix> ANIMATION_MATRIX_PROPERTY =
            new Property<View, Matrix>(Matrix.class, "animationMatrix") {
    /**
     * This property sets the animation matrix properties that are not translations.
     */
    private static final Property<PathAnimatorMatrix, float[]> NON_TRANSLATIONS_PROPERTY =
            new Property<PathAnimatorMatrix, float[]>(float[].class, "nonTranslations") {
                @Override
                public Matrix get(View object) {
                public float[] get(PathAnimatorMatrix object) {
                    return null;
                }

                @Override
                public void set(View object, Matrix value) {
                    object.setAnimationMatrix(value);
                public void set(PathAnimatorMatrix object, float[] value) {
                    object.setValues(value);
                }
            };

    /**
     * This property sets the translation animation matrix properties.
     */
    private static final Property<PathAnimatorMatrix, PointF> TRANSLATIONS_PROPERTY =
            new Property<PathAnimatorMatrix, PointF>(PointF.class, "translations") {
                @Override
                public PointF get(PathAnimatorMatrix object) {
                    return null;
                }

                @Override
                public void set(PathAnimatorMatrix object, PointF value) {
                    object.setTranslation(value);
                }
            };

@@ -261,8 +283,23 @@ public class ChangeTransform extends Transition {
        final View view = endValues.view;
        setIdentityTransforms(view);

        ObjectAnimator animator = ObjectAnimator.ofObject(view, ANIMATION_MATRIX_PROPERTY,
                new TransitionUtils.MatrixEvaluator(), startMatrix, endMatrix);
        final float[] startMatrixValues = new float[9];
        startMatrix.getValues(startMatrixValues);
        final float[] endMatrixValues = new float[9];
        endMatrix.getValues(endMatrixValues);
        final PathAnimatorMatrix pathAnimatorMatrix =
                new PathAnimatorMatrix(view, startMatrixValues);

        PropertyValuesHolder valuesProperty = PropertyValuesHolder.ofObject(
                NON_TRANSLATIONS_PROPERTY, new FloatArrayEvaluator(new float[9]),
                startMatrixValues, endMatrixValues);
        Path path = getPathMotion().getPath(startMatrixValues[Matrix.MTRANS_X],
                startMatrixValues[Matrix.MTRANS_Y], endMatrixValues[Matrix.MTRANS_X],
                endMatrixValues[Matrix.MTRANS_Y]);
        PropertyValuesHolder translationProperty = PropertyValuesHolder.ofObject(
                TRANSLATIONS_PROPERTY, null, path);
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(pathAnimatorMatrix,
                valuesProperty, translationProperty);

        final Matrix finalEndMatrix = endMatrix;

@@ -285,14 +322,13 @@ public class ChangeTransform extends Transition {
                        view.setTagInternal(R.id.parentMatrix, null);
                    }
                }
                ANIMATION_MATRIX_PROPERTY.set(view, null);
                view.setAnimationMatrix(null);
                transforms.restore(view);
            }

            @Override
            public void onAnimationPause(Animator animation) {
                ValueAnimator animator = (ValueAnimator) animation;
                Matrix currentMatrix = (Matrix) animator.getAnimatedValue();
                Matrix currentMatrix = pathAnimatorMatrix.getMatrix();
                setCurrentMatrix(currentMatrix);
            }

@@ -457,4 +493,47 @@ public class ChangeTransform extends Transition {
            mGhostView.setVisibility(View.VISIBLE);
        }
    }

    /**
     * PathAnimatorMatrix allows the translations and the rest of the matrix to be set
     * separately. This allows the PathMotion to affect the translations while scale
     * and rotation are evaluated separately.
     */
    private static class PathAnimatorMatrix {
        private final Matrix mMatrix = new Matrix();
        private final View mView;
        private final float[] mValues;
        private float mTranslationX;
        private float mTranslationY;

        public PathAnimatorMatrix(View view, float[] values) {
            mView = view;
            mValues = values.clone();
            mTranslationX = mValues[Matrix.MTRANS_X];
            mTranslationY = mValues[Matrix.MTRANS_Y];
            setAnimationMatrix();
        }

        public void setValues(float[] values) {
            System.arraycopy(values, 0, mValues, 0, values.length);
            setAnimationMatrix();
        }

        public void setTranslation(PointF translation) {
            mTranslationX = translation.x;
            mTranslationY = translation.y;
            setAnimationMatrix();
        }

        private void setAnimationMatrix() {
            mValues[Matrix.MTRANS_X] = mTranslationX;
            mValues[Matrix.MTRANS_Y] = mTranslationY;
            mMatrix.setValues(mValues);
            mView.setAnimationMatrix(mMatrix);
        }

        public Matrix getMatrix() {
            return mMatrix;
        }
    }
}