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