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