18f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhampackage com.android.launcher3.util;
28f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
38f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.animation.Animator;
48f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.animation.AnimatorListenerAdapter;
58f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.animation.ValueAnimator;
68f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.graphics.Outline;
78f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.graphics.Rect;
88f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.view.View;
98f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport android.view.ViewOutlineProvider;
108f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
118f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhamimport com.android.launcher3.Utilities;
128f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
138f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham/**
148f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham * A {@link ViewOutlineProvider} that has helper functions to create reveal animations.
158f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham * This class should be extended so that subclasses can define the reveal shape as the
168f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham * animation progresses from 0 to 1.
178f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham */
188f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickhampublic abstract class RevealOutlineAnimation extends ViewOutlineProvider {
198f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    protected Rect mOutline;
208f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    protected float mOutlineRadius;
218f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
228f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    public RevealOutlineAnimation() {
238f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        mOutline = new Rect();
248f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    }
258f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
268f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    /** Returns whether elevation should be removed for the duration of the reveal animation. */
278f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    abstract boolean shouldRemoveElevationDuringAnimation();
288f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    /** Sets the progress, from 0 to 1, of the reveal animation. */
298f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    abstract void setProgress(float progress);
308f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
318f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    public ValueAnimator createRevealAnimator(final View revealView) {
32a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal        return createRevealAnimator(revealView, false);
33a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal    }
34a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal
35a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal    public ValueAnimator createRevealAnimator(final View revealView, boolean isReversed) {
36a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal        ValueAnimator va =
37a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal                isReversed ? ValueAnimator.ofFloat(1f, 0f) : ValueAnimator.ofFloat(0f, 1f);
388f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        final float elevation = revealView.getElevation();
398f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
408f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        va.addListener(new AnimatorListenerAdapter() {
410ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham            private boolean mWasCanceled = false;
420ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham
438f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            public void onAnimationStart(Animator animation) {
448f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                revealView.setOutlineProvider(RevealOutlineAnimation.this);
458f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                revealView.setClipToOutline(true);
468f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                if (shouldRemoveElevationDuringAnimation()) {
478f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                    revealView.setTranslationZ(-elevation);
488f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                }
498f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            }
508f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
510ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham            @Override
520ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham            public void onAnimationCancel(Animator animation) {
530ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                mWasCanceled = true;
540ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham            }
550ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham
568f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            public void onAnimationEnd(Animator animation) {
570ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                if (!mWasCanceled) {
580ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                    revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND);
590ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                    revealView.setClipToOutline(false);
600ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                    if (shouldRemoveElevationDuringAnimation()) {
610ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                        revealView.setTranslationZ(0);
620ba81607e30c008a7aa24ca76d74f9c4aaafd053Tony Wickham                    }
638f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                }
648f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            }
658f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
668f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        });
678f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
688f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
698f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            @Override
708f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            public void onAnimationUpdate(ValueAnimator arg0) {
71a2454ad2d8dcffa94f670853eb464726c73597f1Sunny Goyal                float progress = (Float) arg0.getAnimatedValue();
728f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                setProgress(progress);
738f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                revealView.invalidateOutline();
748f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                if (!Utilities.ATLEAST_LOLLIPOP_MR1) {
758f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                    revealView.invalidate();
768f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham                }
778f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham            }
788f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        });
798f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        return va;
808f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    }
818f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham
828f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    @Override
838f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    public void getOutline(View v, Outline outline) {
848f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham        outline.setRoundRect(mOutline, mOutlineRadius);
858f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham    }
868f58e61d02fcb0ca90a2803e76a8792ec2c1f99aTony Wickham}
87