1 /* 2 * Copyright (C) 2010 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.internal.widget; 18 19 import java.util.ArrayList; 20 21 import android.animation.Animator; 22 import android.animation.ObjectAnimator; 23 import android.animation.ValueAnimator; 24 import android.animation.Animator.AnimatorListener; 25 import android.graphics.Canvas; 26 import android.graphics.drawable.BitmapDrawable; 27 import android.util.Log; 28 import android.view.animation.DecelerateInterpolator; 29 30 /** 31 * This class is a container for a Drawable with multiple animated properties. 32 * 33 */ 34 public class DrawableHolder implements AnimatorListener { 35 public static final DecelerateInterpolator EASE_OUT_INTERPOLATOR = new DecelerateInterpolator(); 36 private static final String TAG = "DrawableHolder"; 37 private static final boolean DBG = false; 38 private float mX = 0.0f; 39 private float mY = 0.0f; 40 private float mScaleX = 1.0f; 41 private float mScaleY = 1.0f; 42 private BitmapDrawable mDrawable; 43 private float mAlpha = 1f; 44 private ArrayList<ObjectAnimator> mAnimators = new ArrayList<ObjectAnimator>(); 45 private ArrayList<ObjectAnimator> mNeedToStart = new ArrayList<ObjectAnimator>(); 46 47 public DrawableHolder(BitmapDrawable drawable) { 48 this(drawable, 0.0f, 0.0f); 49 } 50 51 public DrawableHolder(BitmapDrawable drawable, float x, float y) { 52 mDrawable = drawable; 53 mX = x; 54 mY = y; 55 mDrawable.getPaint().setAntiAlias(true); // Force AA 56 mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight()); 57 } 58 59 /** 60 * 61 * Adds an animation that interpolates given property from its current value 62 * to the given value. 63 * 64 * @param duration the duration, in ms. 65 * @param delay the delay to start the animation, in ms. 66 * @param property the property to animate 67 * @param toValue the target value 68 * @param replace if true, replace the current animation with this one. 69 */ 70 public ObjectAnimator addAnimTo(long duration, long delay, 71 String property, float toValue, boolean replace) { 72 73 if (replace) removeAnimationFor(property); 74 75 ObjectAnimator anim = ObjectAnimator.ofFloat(this, property, toValue); 76 anim.setDuration(duration); 77 anim.setStartDelay(delay); 78 anim.setInterpolator(EASE_OUT_INTERPOLATOR); 79 this.addAnimation(anim, replace); 80 if (DBG) Log.v(TAG, "animationCount = " + mAnimators.size()); 81 return anim; 82 } 83 84 /** 85 * Stops all animations for the given property and removes it from the list. 86 * 87 * @param property 88 */ 89 public void removeAnimationFor(String property) { 90 ArrayList<ObjectAnimator> removalList = (ArrayList<ObjectAnimator>)mAnimators.clone(); 91 for (ObjectAnimator currentAnim : removalList) { 92 if (property.equals(currentAnim.getPropertyName())) { 93 currentAnim.cancel(); 94 } 95 } 96 } 97 98 /** 99 * Stops all animations and removes them from the list. 100 */ 101 public void clearAnimations() { 102 for (ObjectAnimator currentAnim : mAnimators) { 103 currentAnim.cancel(); 104 } 105 mAnimators.clear(); 106 } 107 108 /** 109 * Adds the given animation to the list of animations for this object. 110 * 111 * @param anim 112 * @param overwrite 113 * @return 114 */ 115 private DrawableHolder addAnimation(ObjectAnimator anim, boolean overwrite) { 116 if (anim != null) 117 mAnimators.add(anim); 118 mNeedToStart.add(anim); 119 return this; 120 } 121 122 /** 123 * Draw this object to the canvas using the properties defined in this class. 124 * 125 * @param canvas canvas to draw into 126 */ 127 public void draw(Canvas canvas) { 128 final float threshold = 1.0f / 256.0f; // contribution less than 1 LSB of RGB byte 129 if (mAlpha <= threshold) // don't bother if it won't show up 130 return; 131 canvas.save(Canvas.MATRIX_SAVE_FLAG); 132 canvas.translate(mX, mY); 133 canvas.scale(mScaleX, mScaleY); 134 canvas.translate(-0.5f*getWidth(), -0.5f*getHeight()); 135 mDrawable.setAlpha((int) Math.round(mAlpha * 255f)); 136 mDrawable.draw(canvas); 137 canvas.restore(); 138 } 139 140 /** 141 * Starts all animations added since the last call to this function. Used to synchronize 142 * animations. 143 * 144 * @param listener an optional listener to add to the animations. Typically used to know when 145 * to invalidate the surface these are being drawn to. 146 */ 147 public void startAnimations(ValueAnimator.AnimatorUpdateListener listener) { 148 for (int i = 0; i < mNeedToStart.size(); i++) { 149 ObjectAnimator anim = mNeedToStart.get(i); 150 anim.addUpdateListener(listener); 151 anim.addListener(this); 152 anim.start(); 153 } 154 mNeedToStart.clear(); 155 } 156 157 158 public void setX(float value) { 159 mX = value; 160 } 161 162 public void setY(float value) { 163 mY = value; 164 } 165 166 public void setScaleX(float value) { 167 mScaleX = value; 168 } 169 170 public void setScaleY(float value) { 171 mScaleY = value; 172 } 173 174 public void setAlpha(float alpha) { 175 mAlpha = alpha; 176 } 177 178 public float getX() { 179 return mX; 180 } 181 182 public float getY() { 183 return mY; 184 } 185 186 public float getScaleX() { 187 return mScaleX; 188 } 189 190 public float getScaleY() { 191 return mScaleY; 192 } 193 194 public float getAlpha() { 195 return mAlpha; 196 } 197 198 public BitmapDrawable getDrawable() { 199 return mDrawable; 200 } 201 202 public int getWidth() { 203 return mDrawable.getIntrinsicWidth(); 204 } 205 206 public int getHeight() { 207 return mDrawable.getIntrinsicHeight(); 208 } 209 210 public void onAnimationCancel(Animator animation) { 211 212 } 213 214 public void onAnimationEnd(Animator animation) { 215 mAnimators.remove(animation); 216 } 217 218 public void onAnimationRepeat(Animator animation) { 219 220 } 221 222 public void onAnimationStart(Animator animation) { 223 224 } 225 } 226