1 /*
2  * Copyright (C) 2012 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.launcher3;
18 
19 import android.animation.Animator;
20 import android.animation.Animator.AnimatorListener;
21 import android.animation.TimeInterpolator;
22 import android.view.View;
23 import android.view.ViewPropertyAnimator;
24 
25 import java.util.ArrayList;
26 import java.util.EnumSet;
27 
28 public class LauncherViewPropertyAnimator extends Animator implements AnimatorListener {
29     enum Properties {
30             TRANSLATION_X,
31             TRANSLATION_Y,
32             SCALE_X,
33             SCALE_Y,
34             ROTATION_Y,
35             ALPHA,
36             START_DELAY,
37             DURATION,
38             INTERPOLATOR,
39             WITH_LAYER
40     }
41     EnumSet<Properties> mPropertiesToSet = EnumSet.noneOf(Properties.class);
42     ViewPropertyAnimator mViewPropertyAnimator;
43     View mTarget;
44 
45     float mTranslationX;
46     float mTranslationY;
47     float mScaleX;
48     float mScaleY;
49     float mRotationY;
50     float mAlpha;
51     long mStartDelay;
52     long mDuration;
53     TimeInterpolator mInterpolator;
54     ArrayList<Animator.AnimatorListener> mListeners;
55     boolean mRunning = false;
56     FirstFrameAnimatorHelper mFirstFrameHelper;
57 
LauncherViewPropertyAnimator(View target)58     public LauncherViewPropertyAnimator(View target) {
59         mTarget = target;
60         mListeners = new ArrayList<Animator.AnimatorListener>();
61     }
62 
63     @Override
addListener(Animator.AnimatorListener listener)64     public void addListener(Animator.AnimatorListener listener) {
65         mListeners.add(listener);
66     }
67 
68     @Override
cancel()69     public void cancel() {
70         if (mViewPropertyAnimator != null) {
71             mViewPropertyAnimator.cancel();
72         }
73     }
74 
75     @Override
clone()76     public Animator clone() {
77         throw new RuntimeException("Not implemented");
78     }
79 
80     @Override
end()81     public void end() {
82         throw new RuntimeException("Not implemented");
83     }
84 
85     @Override
getDuration()86     public long getDuration() {
87         return mDuration;
88     }
89 
90     @Override
getListeners()91     public ArrayList<Animator.AnimatorListener> getListeners() {
92         return mListeners;
93     }
94 
95     @Override
getStartDelay()96     public long getStartDelay() {
97         return mStartDelay;
98     }
99 
100     @Override
onAnimationCancel(Animator animation)101     public void onAnimationCancel(Animator animation) {
102         for (int i = 0; i < mListeners.size(); i++) {
103             Animator.AnimatorListener listener = mListeners.get(i);
104             listener.onAnimationCancel(this);
105         }
106         mRunning = false;
107     }
108 
109     @Override
onAnimationEnd(Animator animation)110     public void onAnimationEnd(Animator animation) {
111         for (int i = 0; i < mListeners.size(); i++) {
112             Animator.AnimatorListener listener = mListeners.get(i);
113             listener.onAnimationEnd(this);
114         }
115         mRunning = false;
116     }
117 
118     @Override
onAnimationRepeat(Animator animation)119     public void onAnimationRepeat(Animator animation) {
120         for (int i = 0; i < mListeners.size(); i++) {
121             Animator.AnimatorListener listener = mListeners.get(i);
122             listener.onAnimationRepeat(this);
123         }
124     }
125 
126     @Override
onAnimationStart(Animator animation)127     public void onAnimationStart(Animator animation) {
128         // This is the first time we get a handle to the internal ValueAnimator
129         // used by the ViewPropertyAnimator.
130         mFirstFrameHelper.onAnimationStart(animation);
131 
132         for (int i = 0; i < mListeners.size(); i++) {
133             Animator.AnimatorListener listener = mListeners.get(i);
134             listener.onAnimationStart(this);
135         }
136         mRunning = true;
137     }
138 
139     @Override
isRunning()140     public boolean isRunning() {
141         return mRunning;
142     }
143 
144     @Override
isStarted()145     public boolean isStarted() {
146         return mViewPropertyAnimator != null;
147     }
148 
149     @Override
removeAllListeners()150     public void removeAllListeners() {
151         mListeners.clear();
152     }
153 
154     @Override
removeListener(Animator.AnimatorListener listener)155     public void removeListener(Animator.AnimatorListener listener) {
156         mListeners.remove(listener);
157     }
158 
159     @Override
setDuration(long duration)160     public Animator setDuration(long duration) {
161         mPropertiesToSet.add(Properties.DURATION);
162         mDuration = duration;
163         return this;
164     }
165 
166     @Override
setInterpolator(TimeInterpolator value)167     public void setInterpolator(TimeInterpolator value) {
168         mPropertiesToSet.add(Properties.INTERPOLATOR);
169         mInterpolator = value;
170     }
171 
172     @Override
setStartDelay(long startDelay)173     public void setStartDelay(long startDelay) {
174         mPropertiesToSet.add(Properties.START_DELAY);
175         mStartDelay = startDelay;
176     }
177 
178     @Override
setTarget(Object target)179     public void setTarget(Object target) {
180         throw new RuntimeException("Not implemented");
181     }
182 
183     @Override
setupEndValues()184     public void setupEndValues() {
185 
186     }
187 
188     @Override
setupStartValues()189     public void setupStartValues() {
190     }
191 
192     @Override
start()193     public void start() {
194         mViewPropertyAnimator = mTarget.animate();
195 
196         // FirstFrameAnimatorHelper hooks itself up to the updates on the animator,
197         // and then adjusts the play time to keep the first two frames jank-free
198         mFirstFrameHelper = new FirstFrameAnimatorHelper(mViewPropertyAnimator, mTarget);
199 
200         if (mPropertiesToSet.contains(Properties.TRANSLATION_X)) {
201             mViewPropertyAnimator.translationX(mTranslationX);
202         }
203         if (mPropertiesToSet.contains(Properties.TRANSLATION_Y)) {
204             mViewPropertyAnimator.translationY(mTranslationY);
205         }
206         if (mPropertiesToSet.contains(Properties.SCALE_X)) {
207             mViewPropertyAnimator.scaleX(mScaleX);
208         }
209         if (mPropertiesToSet.contains(Properties.ROTATION_Y)) {
210             mViewPropertyAnimator.rotationY(mRotationY);
211         }
212         if (mPropertiesToSet.contains(Properties.SCALE_Y)) {
213             mViewPropertyAnimator.scaleY(mScaleY);
214         }
215         if (mPropertiesToSet.contains(Properties.ALPHA)) {
216             mViewPropertyAnimator.alpha(mAlpha);
217         }
218         if (mPropertiesToSet.contains(Properties.START_DELAY)) {
219             mViewPropertyAnimator.setStartDelay(mStartDelay);
220         }
221         if (mPropertiesToSet.contains(Properties.DURATION)) {
222             mViewPropertyAnimator.setDuration(mDuration);
223         }
224         if (mPropertiesToSet.contains(Properties.INTERPOLATOR)) {
225             mViewPropertyAnimator.setInterpolator(mInterpolator);
226         }
227         if (mPropertiesToSet.contains(Properties.WITH_LAYER)) {
228             mViewPropertyAnimator.withLayer();
229         }
230         mViewPropertyAnimator.setListener(this);
231         mViewPropertyAnimator.start();
232         LauncherAnimUtils.cancelOnDestroyActivity(this);
233     }
234 
translationX(float value)235     public LauncherViewPropertyAnimator translationX(float value) {
236         mPropertiesToSet.add(Properties.TRANSLATION_X);
237         mTranslationX = value;
238         return this;
239     }
240 
translationY(float value)241     public LauncherViewPropertyAnimator translationY(float value) {
242         mPropertiesToSet.add(Properties.TRANSLATION_Y);
243         mTranslationY = value;
244         return this;
245     }
246 
scaleX(float value)247     public LauncherViewPropertyAnimator scaleX(float value) {
248         mPropertiesToSet.add(Properties.SCALE_X);
249         mScaleX = value;
250         return this;
251     }
252 
scaleY(float value)253     public LauncherViewPropertyAnimator scaleY(float value) {
254         mPropertiesToSet.add(Properties.SCALE_Y);
255         mScaleY = value;
256         return this;
257     }
258 
rotationY(float value)259     public LauncherViewPropertyAnimator rotationY(float value) {
260         mPropertiesToSet.add(Properties.ROTATION_Y);
261         mRotationY = value;
262         return this;
263     }
264 
alpha(float value)265     public LauncherViewPropertyAnimator alpha(float value) {
266         mPropertiesToSet.add(Properties.ALPHA);
267         mAlpha = value;
268         return this;
269     }
270 
withLayer()271     public LauncherViewPropertyAnimator withLayer() {
272         mPropertiesToSet.add(Properties.WITH_LAYER);
273         return this;
274     }
275 }
276