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