• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.launcher3.util;
2 
3 import android.animation.Animator;
4 import android.animation.AnimatorListenerAdapter;
5 import android.animation.ValueAnimator;
6 import android.graphics.Outline;
7 import android.graphics.Rect;
8 import android.view.View;
9 import android.view.ViewOutlineProvider;
10 
11 import com.android.launcher3.Utilities;
12 
13 /**
14  * A {@link ViewOutlineProvider} that has helper functions to create reveal animations.
15  * This class should be extended so that subclasses can define the reveal shape as the
16  * animation progresses from 0 to 1.
17  */
18 public abstract class RevealOutlineAnimation extends ViewOutlineProvider {
19     protected Rect mOutline;
20     protected float mOutlineRadius;
21 
RevealOutlineAnimation()22     public RevealOutlineAnimation() {
23         mOutline = new Rect();
24     }
25 
26     /** Returns whether elevation should be removed for the duration of the reveal animation. */
shouldRemoveElevationDuringAnimation()27     abstract boolean shouldRemoveElevationDuringAnimation();
28     /** Sets the progress, from 0 to 1, of the reveal animation. */
setProgress(float progress)29     abstract void setProgress(float progress);
30 
createRevealAnimator(final View revealView)31     public ValueAnimator createRevealAnimator(final View revealView) {
32         return createRevealAnimator(revealView, false);
33     }
34 
createRevealAnimator(final View revealView, boolean isReversed)35     public ValueAnimator createRevealAnimator(final View revealView, boolean isReversed) {
36         ValueAnimator va =
37                 isReversed ? ValueAnimator.ofFloat(1f, 0f) : ValueAnimator.ofFloat(0f, 1f);
38         final float elevation = revealView.getElevation();
39 
40         va.addListener(new AnimatorListenerAdapter() {
41             private boolean mWasCanceled = false;
42 
43             public void onAnimationStart(Animator animation) {
44                 revealView.setOutlineProvider(RevealOutlineAnimation.this);
45                 revealView.setClipToOutline(true);
46                 if (shouldRemoveElevationDuringAnimation()) {
47                     revealView.setTranslationZ(-elevation);
48                 }
49             }
50 
51             @Override
52             public void onAnimationCancel(Animator animation) {
53                 mWasCanceled = true;
54             }
55 
56             public void onAnimationEnd(Animator animation) {
57                 if (!mWasCanceled) {
58                     revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND);
59                     revealView.setClipToOutline(false);
60                     if (shouldRemoveElevationDuringAnimation()) {
61                         revealView.setTranslationZ(0);
62                     }
63                 }
64             }
65 
66         });
67 
68         va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
69             @Override
70             public void onAnimationUpdate(ValueAnimator arg0) {
71                 float progress = (Float) arg0.getAnimatedValue();
72                 setProgress(progress);
73                 revealView.invalidateOutline();
74                 if (!Utilities.ATLEAST_LOLLIPOP_MR1) {
75                     revealView.invalidate();
76                 }
77             }
78         });
79         return va;
80     }
81 
82     @Override
getOutline(View v, Outline outline)83     public void getOutline(View v, Outline outline) {
84         outline.setRoundRect(mOutline, mOutlineRadius);
85     }
86 }
87