13060421045d4d9e411797f91bb509824b03e33fbJim Miller/* 23060421045d4d9e411797f91bb509824b03e33fbJim Miller * Copyright (C) 2010 The Android Open Source Project 33060421045d4d9e411797f91bb509824b03e33fbJim Miller * 43060421045d4d9e411797f91bb509824b03e33fbJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 53060421045d4d9e411797f91bb509824b03e33fbJim Miller * you may not use this file except in compliance with the License. 63060421045d4d9e411797f91bb509824b03e33fbJim Miller * You may obtain a copy of the License at 73060421045d4d9e411797f91bb509824b03e33fbJim Miller * 83060421045d4d9e411797f91bb509824b03e33fbJim Miller * http://www.apache.org/licenses/LICENSE-2.0 93060421045d4d9e411797f91bb509824b03e33fbJim Miller * 103060421045d4d9e411797f91bb509824b03e33fbJim Miller * Unless required by applicable law or agreed to in writing, software 113060421045d4d9e411797f91bb509824b03e33fbJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 123060421045d4d9e411797f91bb509824b03e33fbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133060421045d4d9e411797f91bb509824b03e33fbJim Miller * See the License for the specific language governing permissions and 143060421045d4d9e411797f91bb509824b03e33fbJim Miller * limitations under the License. 153060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 163060421045d4d9e411797f91bb509824b03e33fbJim Miller 173060421045d4d9e411797f91bb509824b03e33fbJim Millerpackage com.android.internal.widget; 183060421045d4d9e411797f91bb509824b03e33fbJim Miller 193060421045d4d9e411797f91bb509824b03e33fbJim Millerimport java.util.ArrayList; 203060421045d4d9e411797f91bb509824b03e33fbJim Miller 213060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.animation.Animator; 223060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.animation.ObjectAnimator; 233060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.animation.ValueAnimator; 243060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.animation.Animator.AnimatorListener; 253060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.graphics.Canvas; 263060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.graphics.drawable.BitmapDrawable; 273060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.util.Log; 283060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.view.animation.DecelerateInterpolator; 293060421045d4d9e411797f91bb509824b03e33fbJim Miller 303060421045d4d9e411797f91bb509824b03e33fbJim Miller/** 313060421045d4d9e411797f91bb509824b03e33fbJim Miller * This class is a container for a Drawable with multiple animated properties. 323060421045d4d9e411797f91bb509824b03e33fbJim Miller * 333060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 343060421045d4d9e411797f91bb509824b03e33fbJim Millerpublic class DrawableHolder implements AnimatorListener { 353060421045d4d9e411797f91bb509824b03e33fbJim Miller public static final DecelerateInterpolator EASE_OUT_INTERPOLATOR = new DecelerateInterpolator(); 363060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final String TAG = "DrawableHolder"; 373060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final boolean DBG = false; 383060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mX = 0.0f; 393060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mY = 0.0f; 403060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mScaleX = 1.0f; 413060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mScaleY = 1.0f; 423060421045d4d9e411797f91bb509824b03e33fbJim Miller private BitmapDrawable mDrawable; 433060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mAlpha = 1f; 442794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase private ArrayList<ObjectAnimator> mAnimators = new ArrayList<ObjectAnimator>(); 452794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase private ArrayList<ObjectAnimator> mNeedToStart = new ArrayList<ObjectAnimator>(); 463060421045d4d9e411797f91bb509824b03e33fbJim Miller 473060421045d4d9e411797f91bb509824b03e33fbJim Miller public DrawableHolder(BitmapDrawable drawable) { 483060421045d4d9e411797f91bb509824b03e33fbJim Miller this(drawable, 0.0f, 0.0f); 493060421045d4d9e411797f91bb509824b03e33fbJim Miller } 503060421045d4d9e411797f91bb509824b03e33fbJim Miller 513060421045d4d9e411797f91bb509824b03e33fbJim Miller public DrawableHolder(BitmapDrawable drawable, float x, float y) { 523060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawable = drawable; 533060421045d4d9e411797f91bb509824b03e33fbJim Miller mX = x; 543060421045d4d9e411797f91bb509824b03e33fbJim Miller mY = y; 553060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawable.getPaint().setAntiAlias(true); // Force AA 563060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight()); 573060421045d4d9e411797f91bb509824b03e33fbJim Miller } 583060421045d4d9e411797f91bb509824b03e33fbJim Miller 593060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 603060421045d4d9e411797f91bb509824b03e33fbJim Miller * 613060421045d4d9e411797f91bb509824b03e33fbJim Miller * Adds an animation that interpolates given property from its current value 623060421045d4d9e411797f91bb509824b03e33fbJim Miller * to the given value. 633060421045d4d9e411797f91bb509824b03e33fbJim Miller * 643060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param duration the duration, in ms. 653060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param delay the delay to start the animation, in ms. 663060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param property the property to animate 673060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param toValue the target value 683060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param replace if true, replace the current animation with this one. 693060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 702794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public ObjectAnimator addAnimTo(long duration, long delay, 713060421045d4d9e411797f91bb509824b03e33fbJim Miller String property, float toValue, boolean replace) { 723060421045d4d9e411797f91bb509824b03e33fbJim Miller 733060421045d4d9e411797f91bb509824b03e33fbJim Miller if (replace) removeAnimationFor(property); 743060421045d4d9e411797f91bb509824b03e33fbJim Miller 752794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = ObjectAnimator.ofFloat(this, property, toValue); 762794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setDuration(duration); 773060421045d4d9e411797f91bb509824b03e33fbJim Miller anim.setStartDelay(delay); 783060421045d4d9e411797f91bb509824b03e33fbJim Miller anim.setInterpolator(EASE_OUT_INTERPOLATOR); 793060421045d4d9e411797f91bb509824b03e33fbJim Miller this.addAnimation(anim, replace); 803060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "animationCount = " + mAnimators.size()); 813060421045d4d9e411797f91bb509824b03e33fbJim Miller return anim; 823060421045d4d9e411797f91bb509824b03e33fbJim Miller } 833060421045d4d9e411797f91bb509824b03e33fbJim Miller 843060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 853060421045d4d9e411797f91bb509824b03e33fbJim Miller * Stops all animations for the given property and removes it from the list. 863060421045d4d9e411797f91bb509824b03e33fbJim Miller * 873060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param property 883060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 893060421045d4d9e411797f91bb509824b03e33fbJim Miller public void removeAnimationFor(String property) { 90e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase ArrayList<ObjectAnimator> removalList = (ArrayList<ObjectAnimator>)mAnimators.clone(); 91e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase for (ObjectAnimator currentAnim : removalList) { 923060421045d4d9e411797f91bb509824b03e33fbJim Miller if (property.equals(currentAnim.getPropertyName())) { 933060421045d4d9e411797f91bb509824b03e33fbJim Miller currentAnim.cancel(); 943060421045d4d9e411797f91bb509824b03e33fbJim Miller } 953060421045d4d9e411797f91bb509824b03e33fbJim Miller } 963060421045d4d9e411797f91bb509824b03e33fbJim Miller } 973060421045d4d9e411797f91bb509824b03e33fbJim Miller 983060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 993060421045d4d9e411797f91bb509824b03e33fbJim Miller * Stops all animations and removes them from the list. 1003060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 1013060421045d4d9e411797f91bb509824b03e33fbJim Miller public void clearAnimations() { 1022794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase for (ObjectAnimator currentAnim : mAnimators) { 1033060421045d4d9e411797f91bb509824b03e33fbJim Miller currentAnim.cancel(); 1043060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1053060421045d4d9e411797f91bb509824b03e33fbJim Miller mAnimators.clear(); 1063060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1073060421045d4d9e411797f91bb509824b03e33fbJim Miller 1083060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 1093060421045d4d9e411797f91bb509824b03e33fbJim Miller * Adds the given animation to the list of animations for this object. 1103060421045d4d9e411797f91bb509824b03e33fbJim Miller * 1113060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param anim 1123060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param overwrite 1133060421045d4d9e411797f91bb509824b03e33fbJim Miller * @return 1143060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 1152794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase private DrawableHolder addAnimation(ObjectAnimator anim, boolean overwrite) { 1163060421045d4d9e411797f91bb509824b03e33fbJim Miller if (anim != null) 1173060421045d4d9e411797f91bb509824b03e33fbJim Miller mAnimators.add(anim); 1183060421045d4d9e411797f91bb509824b03e33fbJim Miller mNeedToStart.add(anim); 1193060421045d4d9e411797f91bb509824b03e33fbJim Miller return this; 1203060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1213060421045d4d9e411797f91bb509824b03e33fbJim Miller 1223060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 1233060421045d4d9e411797f91bb509824b03e33fbJim Miller * Draw this object to the canvas using the properties defined in this class. 1243060421045d4d9e411797f91bb509824b03e33fbJim Miller * 1253060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param canvas canvas to draw into 1263060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 1273060421045d4d9e411797f91bb509824b03e33fbJim Miller public void draw(Canvas canvas) { 1283060421045d4d9e411797f91bb509824b03e33fbJim Miller final float threshold = 1.0f / 256.0f; // contribution less than 1 LSB of RGB byte 1293060421045d4d9e411797f91bb509824b03e33fbJim Miller if (mAlpha <= threshold) // don't bother if it won't show up 1303060421045d4d9e411797f91bb509824b03e33fbJim Miller return; 1313060421045d4d9e411797f91bb509824b03e33fbJim Miller canvas.save(Canvas.MATRIX_SAVE_FLAG); 1323060421045d4d9e411797f91bb509824b03e33fbJim Miller canvas.translate(mX, mY); 1333060421045d4d9e411797f91bb509824b03e33fbJim Miller canvas.scale(mScaleX, mScaleY); 1343060421045d4d9e411797f91bb509824b03e33fbJim Miller canvas.translate(-0.5f*getWidth(), -0.5f*getHeight()); 1353060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawable.setAlpha((int) Math.round(mAlpha * 255f)); 1363060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawable.draw(canvas); 1373060421045d4d9e411797f91bb509824b03e33fbJim Miller canvas.restore(); 1383060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1393060421045d4d9e411797f91bb509824b03e33fbJim Miller 1403060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 1413060421045d4d9e411797f91bb509824b03e33fbJim Miller * Starts all animations added since the last call to this function. Used to synchronize 1423060421045d4d9e411797f91bb509824b03e33fbJim Miller * animations. 1433060421045d4d9e411797f91bb509824b03e33fbJim Miller * 1443060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param listener an optional listener to add to the animations. Typically used to know when 1453060421045d4d9e411797f91bb509824b03e33fbJim Miller * to invalidate the surface these are being drawn to. 1463060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 1473060421045d4d9e411797f91bb509824b03e33fbJim Miller public void startAnimations(ValueAnimator.AnimatorUpdateListener listener) { 1483060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mNeedToStart.size(); i++) { 1492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = mNeedToStart.get(i); 1503060421045d4d9e411797f91bb509824b03e33fbJim Miller anim.addUpdateListener(listener); 1513060421045d4d9e411797f91bb509824b03e33fbJim Miller anim.addListener(this); 1523060421045d4d9e411797f91bb509824b03e33fbJim Miller anim.start(); 1533060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1543060421045d4d9e411797f91bb509824b03e33fbJim Miller mNeedToStart.clear(); 1553060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1563060421045d4d9e411797f91bb509824b03e33fbJim Miller 1573060421045d4d9e411797f91bb509824b03e33fbJim Miller 158c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller public void setX(float value) { 1593060421045d4d9e411797f91bb509824b03e33fbJim Miller mX = value; 1603060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1613060421045d4d9e411797f91bb509824b03e33fbJim Miller 162c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller public void setY(float value) { 1633060421045d4d9e411797f91bb509824b03e33fbJim Miller mY = value; 1643060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1653060421045d4d9e411797f91bb509824b03e33fbJim Miller 166c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller public void setScaleX(float value) { 1673060421045d4d9e411797f91bb509824b03e33fbJim Miller mScaleX = value; 1683060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1693060421045d4d9e411797f91bb509824b03e33fbJim Miller 170c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller public void setScaleY(float value) { 1713060421045d4d9e411797f91bb509824b03e33fbJim Miller mScaleY = value; 1723060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1733060421045d4d9e411797f91bb509824b03e33fbJim Miller 174c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller public void setAlpha(float alpha) { 1753060421045d4d9e411797f91bb509824b03e33fbJim Miller mAlpha = alpha; 1763060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1773060421045d4d9e411797f91bb509824b03e33fbJim Miller 1783060421045d4d9e411797f91bb509824b03e33fbJim Miller public float getX() { 1793060421045d4d9e411797f91bb509824b03e33fbJim Miller return mX; 1803060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1813060421045d4d9e411797f91bb509824b03e33fbJim Miller 1823060421045d4d9e411797f91bb509824b03e33fbJim Miller public float getY() { 1833060421045d4d9e411797f91bb509824b03e33fbJim Miller return mY; 1843060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1853060421045d4d9e411797f91bb509824b03e33fbJim Miller 1863060421045d4d9e411797f91bb509824b03e33fbJim Miller public float getScaleX() { 1873060421045d4d9e411797f91bb509824b03e33fbJim Miller return mScaleX; 1883060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1893060421045d4d9e411797f91bb509824b03e33fbJim Miller 1903060421045d4d9e411797f91bb509824b03e33fbJim Miller public float getScaleY() { 1913060421045d4d9e411797f91bb509824b03e33fbJim Miller return mScaleY; 1923060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1933060421045d4d9e411797f91bb509824b03e33fbJim Miller 1943060421045d4d9e411797f91bb509824b03e33fbJim Miller public float getAlpha() { 1953060421045d4d9e411797f91bb509824b03e33fbJim Miller return mAlpha; 1963060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1973060421045d4d9e411797f91bb509824b03e33fbJim Miller 1983060421045d4d9e411797f91bb509824b03e33fbJim Miller public BitmapDrawable getDrawable() { 1993060421045d4d9e411797f91bb509824b03e33fbJim Miller return mDrawable; 2003060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2013060421045d4d9e411797f91bb509824b03e33fbJim Miller 2023060421045d4d9e411797f91bb509824b03e33fbJim Miller public int getWidth() { 2033060421045d4d9e411797f91bb509824b03e33fbJim Miller return mDrawable.getIntrinsicWidth(); 2043060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2053060421045d4d9e411797f91bb509824b03e33fbJim Miller 2063060421045d4d9e411797f91bb509824b03e33fbJim Miller public int getHeight() { 2073060421045d4d9e411797f91bb509824b03e33fbJim Miller return mDrawable.getIntrinsicHeight(); 2083060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2093060421045d4d9e411797f91bb509824b03e33fbJim Miller 2103060421045d4d9e411797f91bb509824b03e33fbJim Miller public void onAnimationCancel(Animator animation) { 2113060421045d4d9e411797f91bb509824b03e33fbJim Miller 2123060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2133060421045d4d9e411797f91bb509824b03e33fbJim Miller 2143060421045d4d9e411797f91bb509824b03e33fbJim Miller public void onAnimationEnd(Animator animation) { 2153060421045d4d9e411797f91bb509824b03e33fbJim Miller mAnimators.remove(animation); 2163060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2173060421045d4d9e411797f91bb509824b03e33fbJim Miller 2183060421045d4d9e411797f91bb509824b03e33fbJim Miller public void onAnimationRepeat(Animator animation) { 2193060421045d4d9e411797f91bb509824b03e33fbJim Miller 2203060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2213060421045d4d9e411797f91bb509824b03e33fbJim Miller 2223060421045d4d9e411797f91bb509824b03e33fbJim Miller public void onAnimationStart(Animator animation) { 2233060421045d4d9e411797f91bb509824b03e33fbJim Miller 2243060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2253060421045d4d9e411797f91bb509824b03e33fbJim Miller} 226