1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.recents.utilities;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorSet;
21 import android.animation.ValueAnimator;
22 import android.annotation.IntDef;
23 import android.util.SparseArray;
24 import android.util.SparseLongArray;
25 import android.view.View;
26 import android.view.animation.Interpolator;
27 import android.view.animation.LinearInterpolator;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.List;
32 
33 /**
34  * The generic set of animation properties to animate a {@link View}. The animation can have
35  * different interpolators, start delays and durations for each of the different properties.
36  */
37 public class AnimationProps {
38 
39     private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
40     public static final AnimationProps IMMEDIATE = new AnimationProps(0, LINEAR_INTERPOLATOR);
41 
42     @Retention(RetentionPolicy.SOURCE)
43     @IntDef({ALL, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, ALPHA, SCALE, BOUNDS})
44     public @interface PropType {}
45 
46     public static final int ALL = 0;
47     public static final int TRANSLATION_X = 1;
48     public static final int TRANSLATION_Y = 2;
49     public static final int TRANSLATION_Z = 3;
50     public static final int ALPHA = 4;
51     public static final int SCALE = 5;
52     public static final int BOUNDS = 6;
53     public static final int DIM_ALPHA = 7;
54 
55     private SparseLongArray mPropStartDelay;
56     private SparseLongArray mPropDuration;
57     private SparseArray<Interpolator> mPropInterpolators;
58     private Animator.AnimatorListener mListener;
59 
60     /**
61      * The builder constructor.
62      */
AnimationProps()63     public AnimationProps() {}
64 
65     /**
66      * Creates an animation with a default {@param duration} and {@param interpolator} for all
67      * properties in this animation.
68      */
AnimationProps(int duration, Interpolator interpolator)69     public AnimationProps(int duration, Interpolator interpolator) {
70         this(0, duration, interpolator, null);
71     }
72 
73     /**
74      * Creates an animation with a default {@param duration} and {@param interpolator} for all
75      * properties in this animation.
76      */
AnimationProps(int duration, Interpolator interpolator, Animator.AnimatorListener listener)77     public AnimationProps(int duration, Interpolator interpolator,
78             Animator.AnimatorListener listener) {
79         this(0, duration, interpolator, listener);
80     }
81 
82     /**
83      * Creates an animation with a default {@param startDelay}, {@param duration} and
84      * {@param interpolator} for all properties in this animation.
85      */
AnimationProps(int startDelay, int duration, Interpolator interpolator)86     public AnimationProps(int startDelay, int duration, Interpolator interpolator) {
87         this(startDelay, duration, interpolator, null);
88     }
89 
90     /**
91      * Creates an animation with a default {@param startDelay}, {@param duration} and
92      * {@param interpolator} for all properties in this animation.
93      */
AnimationProps(int startDelay, int duration, Interpolator interpolator, Animator.AnimatorListener listener)94     public AnimationProps(int startDelay, int duration, Interpolator interpolator,
95             Animator.AnimatorListener listener) {
96         setStartDelay(ALL, startDelay);
97         setDuration(ALL, duration);
98         setInterpolator(ALL, interpolator);
99         setListener(listener);
100     }
101 
102     /**
103      * Creates a new {@link AnimatorSet} that will animate the given animators.  Callers need to
104      * manually apply the individual animation properties for each of the animators respectively.
105      */
createAnimator(List<Animator> animators)106     public AnimatorSet createAnimator(List<Animator> animators) {
107         AnimatorSet anim = new AnimatorSet();
108         if (mListener != null) {
109             anim.addListener(mListener);
110         }
111         anim.playTogether(animators);
112         return anim;
113     }
114 
115     /**
116      * Applies the specific start delay, duration and interpolator to the given {@param animator}
117      * for the specified {@param propertyType}.
118      */
apply(@ropType int propertyType, T animator)119     public <T extends ValueAnimator> T apply(@PropType int propertyType, T animator) {
120         animator.setStartDelay(getStartDelay(propertyType));
121         animator.setDuration(getDuration(propertyType));
122         animator.setInterpolator(getInterpolator(propertyType));
123         return animator;
124     }
125 
126     /**
127      * Sets a start delay for a specific property.
128      */
setStartDelay(@ropType int propertyType, int startDelay)129     public AnimationProps setStartDelay(@PropType int propertyType, int startDelay) {
130         if (mPropStartDelay == null) {
131             mPropStartDelay = new SparseLongArray();
132         }
133         mPropStartDelay.append(propertyType, startDelay);
134         return this;
135     }
136 
137     /**
138      * Returns the start delay for a specific property.
139      */
getStartDelay(@ropType int propertyType)140     public long getStartDelay(@PropType int propertyType) {
141         if (mPropStartDelay != null) {
142             long startDelay = mPropStartDelay.get(propertyType, -1);
143             if (startDelay != -1) {
144                 return startDelay;
145             }
146             return mPropStartDelay.get(ALL, 0);
147         }
148         return 0;
149     }
150 
151     /**
152      * Sets a duration for a specific property.
153      */
setDuration(@ropType int propertyType, int duration)154     public AnimationProps setDuration(@PropType int propertyType, int duration) {
155         if (mPropDuration == null) {
156             mPropDuration = new SparseLongArray();
157         }
158         mPropDuration.append(propertyType, duration);
159         return this;
160     }
161 
162     /**
163      * Returns the duration for a specific property.
164      */
getDuration(@ropType int propertyType)165     public long getDuration(@PropType int propertyType) {
166         if (mPropDuration != null) {
167             long duration = mPropDuration.get(propertyType, -1);
168             if (duration != -1) {
169                 return duration;
170             }
171             return mPropDuration.get(ALL, 0);
172         }
173         return 0;
174     }
175 
176     /**
177      * Sets an interpolator for a specific property.
178      */
setInterpolator(@ropType int propertyType, Interpolator interpolator)179     public AnimationProps setInterpolator(@PropType int propertyType, Interpolator interpolator) {
180         if (mPropInterpolators == null) {
181             mPropInterpolators = new SparseArray<>();
182         }
183         mPropInterpolators.append(propertyType, interpolator);
184         return this;
185     }
186 
187     /**
188      * Returns the interpolator for a specific property, falling back to the general interpolator
189      * if there is no specific property interpolator.
190      */
getInterpolator(@ropType int propertyType)191     public Interpolator getInterpolator(@PropType int propertyType) {
192         if (mPropInterpolators != null) {
193             Interpolator interp = mPropInterpolators.get(propertyType);
194             if (interp != null) {
195                 return interp;
196             }
197             return mPropInterpolators.get(ALL, LINEAR_INTERPOLATOR);
198         }
199         return LINEAR_INTERPOLATOR;
200     }
201 
202     /**
203      * Sets an animator listener for this animation.
204      */
setListener(Animator.AnimatorListener listener)205     public AnimationProps setListener(Animator.AnimatorListener listener) {
206         mListener = listener;
207         return this;
208     }
209 
210     /**
211      * Returns the animator listener for this animation.
212      */
getListener()213     public Animator.AnimatorListener getListener() {
214         return mListener;
215     }
216 
217     /**
218      * Returns whether this animation has any duration.
219      */
isImmediate()220     public boolean isImmediate() {
221         int count = mPropDuration.size();
222         for (int i = 0; i < count; i++) {
223             if (mPropDuration.valueAt(i) > 0) {
224                 return false;
225             }
226         }
227         return true;
228     }
229 }
230