DrawableContainer.java revision d9e788c4f0528e46db4a035cfac043736becb0d1
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19c2974809373697147cbe5754835cc871fb93aef1Dianne Hackbornimport android.content.res.Resources; 2078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Canvas; 2178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.ColorFilter; 22bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milneimport android.graphics.Insets; 2378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PixelFormat; 2478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Rect; 25079e23575024e103358c982152afb7a720ae1a8aDianne Hackbornimport android.os.SystemClock; 26600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglioimport android.util.LayoutDirection; 27f390f770ee570f1f4def41b165cb9492e381be40Alan Viveretteimport android.util.SparseArray; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne/** 3078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A helper class that contains several {@link Drawable}s and selects which one to use. 3178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * 3278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * You can subclass it to create your own DrawableContainers or directly use one its child classes. 3378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DrawableContainer extends Drawable implements Drawable.Callback { 35079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private static final boolean DEBUG = false; 36079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private static final String TAG = "DrawableContainer"; 37211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed 38211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed /** 39211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * To be proper, we should have a getter for dither (and alpha, etc.) 40211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * so that proxy classes like this can save/restore their delegates' 41211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * values, but we don't have getters. Since we do have setters 42211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * (e.g. setDither), which this proxy forwards on, we have to have some 43211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * default/initial setting. 44211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * 45211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * The initial setting for dither is now true, since it almost always seems 46211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * to improve the quality at negligible cost. 47211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed */ 48211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed private static final boolean DEFAULT_DITHER = true; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private DrawableContainerState mDrawableContainerState; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mCurrDrawable; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mAlpha = 0xFF; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mCurIndex = -1; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Animations. 57079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private Runnable mAnimationRunnable; 58079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private long mEnterAnimationEnd; 59079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private long mExitAnimationEnd; 60079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private Drawable mLastDrawable; 61079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 62f68bb66c6ec239790ba18b8d078eb7ab4894fdc3John Spurlock private Insets mInsets = Insets.NONE; 63600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // overrides from Drawable 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.draw(canvas); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 71079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 72079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.draw(canvas); 73079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mDrawableContainerState.mChangingConfigurations 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mDrawableContainerState.mChildrenChangingConfigurations; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 82f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 83600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio private boolean needsMirroring() { 84600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 85600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 86600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect r = mDrawableContainerState.getConstantPadding(); 90f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio boolean result; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r != null) { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project padding.set(r); 93f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio result = (r.left | r.top | r.bottom | r.right) != 0; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 95600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio if (mCurrDrawable != null) { 96600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio result = mCurrDrawable.getPadding(padding); 97600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } else { 98600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio result = super.getPadding(padding); 99600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 101600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio if (needsMirroring()) { 102600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio final int left = padding.left; 103600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio final int right = padding.right; 104600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio padding.left = right; 105600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio padding.right = left; 106600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 107600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return result; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1101557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne /** 1111557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne * @hide 1121557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne */ 1131557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne @Override 1147b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne public Insets getOpticalInsets() { 115600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return mInsets; 1161557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne } 1171557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAlpha != alpha) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlpha = alpha; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 123079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd == 0) { 1245f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(alpha); 125079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 126079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(false); 127079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 133b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 134b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mAlpha; 135b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 136b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 137b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 139a41581ed4033004c73115113f45b9844e9b0210fRomain Guy if (mDrawableContainerState.mDither != dither) { 140a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDrawableContainerState.mDither = dither; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1425f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setDither(mDrawableContainerState.mDither); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter cf) { 149d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette if (mDrawableContainerState.mColorFilter != cf) { 150d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette mDrawableContainerState.mColorFilter = cf; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1525f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setColorFilter(cf); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 156f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 157079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 158079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is entering 159079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 160079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 161079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 162079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setEnterFadeDuration(int ms) { 163079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mEnterFadeDuration = ms; 164079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 165f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 166079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 167079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is leaving 168079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 169079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 170079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 171079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setExitFadeDuration(int ms) { 172079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mExitFadeDuration = ms; 173079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 174f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 177079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 178079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setBounds(bounds); 179079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setBounds(bounds); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 184f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.isStateful(); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 189f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1913f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public void setAutoMirrored(boolean mirrored) { 1923f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mDrawableContainerState.mAutoMirrored = mirrored; 1933f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio if (mCurrDrawable != null) { 1943f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored); 1953f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 1963f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 1973f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 1983f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 1993f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public boolean isAutoMirrored() { 2003f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio return mDrawableContainerState.mAutoMirrored; 2013f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2023f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 2033f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 204079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void jumpToCurrentState() { 205079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean changed = false; 206079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 207079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.jumpToCurrentState(); 208079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 209079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 210079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 211079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 212079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.jumpToCurrentState(); 2135f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(mAlpha); 214079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 215079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 216079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 217079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 218079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 219079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 220079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 221079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 222079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 223079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (changed) { 224079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 225079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 226079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 227079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 228079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onStateChange(int[] state) { 230079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 231079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setState(state); 232079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setState(state); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onLevelChange(int level) { 241079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 242079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setLevel(level); 243079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setLevel(level); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantWidth(); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantHeight(); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 265f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumWidth() { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumWidth(); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumHeight() { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumHeight(); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28272146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 283079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void invalidateDrawable(Drawable who) { 284f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 285f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().invalidateDrawable(this); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28972146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 290079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void scheduleDrawable(Drawable who, Runnable what, long when) { 291f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 292f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().scheduleDrawable(this, what, when); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29672146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 297079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void unscheduleDrawable(Drawable who, Runnable what) { 298f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 299f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().unscheduleDrawable(this, what); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setVisible(boolean visible, boolean restart) { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed = super.setVisible(visible, restart); 306079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 307079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(visible, restart); 308079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setVisible(visible, restart); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return changed; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 31783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT : 31883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy mDrawableContainerState.getOpacity(); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne public boolean selectDrawable(int idx) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx == mCurIndex) { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 325079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 326079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 327079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 328079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx 329079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + ": exit=" + mDrawableContainerState.mExitFadeDuration 330079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + " enter=" + mDrawableContainerState.mEnterFadeDuration); 331079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 332079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mExitFadeDuration > 0) { 333079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 334079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 335079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 337079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = mCurrDrawable; 338079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration; 339079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 340079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 341079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 343079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else if (mCurrDrawable != null) { 344079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.setVisible(false, false); 345079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 346079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 347079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) { 348f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable d = mDrawableContainerState.getChild(idx); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = d; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIndex = idx; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d != null) { 352600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio mInsets = d.getOpticalInsets(); 3535f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy d.mutate(); 354079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mEnterFadeDuration > 0) { 355079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration; 356079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 357079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn d.setAlpha(mAlpha); 358079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setVisible(isVisible(), true); 360a41581ed4033004c73115113f45b9844e9b0210fRomain Guy d.setDither(mDrawableContainerState.mDither); 361d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette d.setColorFilter(mDrawableContainerState.mColorFilter); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setState(getState()); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setLevel(getLevel()); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setBounds(getBounds()); 365731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio d.setLayoutDirection(getLayoutDirection()); 3663f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio d.setAutoMirrored(mDrawableContainerState.mAutoMirrored); 367600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } else { 368600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio mInsets = Insets.NONE; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = null; 372600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio mInsets = Insets.NONE; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIndex = -1; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 375079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 376079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) { 377079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mAnimationRunnable == null) { 378079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mAnimationRunnable = new Runnable() { 379079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override public void run() { 380079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 381079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 382079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 383079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn }; 384079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 385079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn unscheduleSelf(mAnimationRunnable); 386079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 387079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Compute first frame and schedule next animation. 388079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 389079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 390079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 392079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 395f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 396079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn void animate(boolean schedule) { 397079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 398079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean animating = false; 399079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 400079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 401079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd <= now) { 4025f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(mAlpha); 403079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 404079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 405079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mEnterAnimationEnd-now)*255) 406079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mEnterFadeDuration; 407079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha); 4085f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(((255-animAlpha)*mAlpha)/255); 409079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 410079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 411079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 412079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 413079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 414079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 415079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 416079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 417079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd <= now) { 418079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 419079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 420079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 421079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 422079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mExitAnimationEnd-now)*255) 423079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mExitFadeDuration; 424079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha); 4255f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mLastDrawable.mutate().setAlpha((animAlpha*mAlpha)/255); 426079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 427079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 428079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 429079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 430079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 431079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 432079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 433079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (schedule && animating) { 434079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn scheduleSelf(mAnimationRunnable, now + 1000/60); 435079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 436079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 437079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getCurrent() { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.canConstantState()) { 4466efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mDrawableContainerState.mChangingConfigurations = getChangingConfigurations(); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 45572146433322588c1116ee06c27ac758ad09d869cAlan Viverette mDrawableContainerState.mutate(); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne /** 46278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A ConstantState that can contain several {@link Drawable}s. 46378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * 46478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * This class was made public to enable testing, and its visibility may change in a future 46578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * release. 46678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */ 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract static class DrawableContainerState extends ConstantState { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DrawableContainer mOwner; 469f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Resources mRes; 470f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 471f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette SparseArray<ConstantStateFuture> mDrawableFutures; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 473f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mChangingConfigurations; 474f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mChildrenChangingConfigurations; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 476f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Drawable[] mDrawables; 477f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mNumChildren; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mVariablePadding; 480f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mPaddingChecked; 481f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Rect mConstantPadding; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 483f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mConstantSize; 484f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mComputedConstantSize; 485f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantWidth; 486f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantHeight; 487f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumWidth; 488f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumHeight; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 490f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedOpacity; 491f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mOpacity; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 493f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedStateful; 494f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mStateful; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 496f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedConstantState; 497f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCanConstantState; 4985140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy 499f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mDither = DEFAULT_DITHER; 500f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 501f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mMutated; 502f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mLayoutDirection; 503f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 504f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mEnterFadeDuration; 505f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mExitFadeDuration; 506079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 5073f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio boolean mAutoMirrored; 5083f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 509d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette ColorFilter mColorFilter; 510d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette 511c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, 512c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn Resources res) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwner = owner; 514f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mRes = res; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (orig != null) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = orig.mChangingConfigurations; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 520f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 521f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = orig.mVariablePadding; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = orig.mConstantSize; 525a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDither = orig.mDither; 526f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = orig.mMutated; 527f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = orig.mLayoutDirection; 528079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = orig.mEnterFadeDuration; 529079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = orig.mExitFadeDuration; 5303f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mAutoMirrored = orig.mAutoMirrored; 531d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette mColorFilter = orig.mColorFilter; 532079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 533f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Cloning the following values may require creating futures. 534f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantPadding = orig.getConstantPadding(); 535f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mPaddingChecked = true; 536f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 537f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantWidth = orig.getConstantWidth(); 538f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantHeight = orig.getConstantHeight(); 539f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantMinimumWidth = orig.getConstantMinimumWidth(); 540f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantMinimumHeight = orig.getConstantMinimumHeight(); 541f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mComputedConstantSize = true; 542f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 543f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mOpacity = orig.getOpacity(); 544f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = true; 545f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 546f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = orig.isStateful(); 547f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = true; 548f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 549f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Postpone cloning children and futures until we're absolutely 550f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // sure that we're done computing values for the original state. 551f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] origDr = orig.mDrawables; 552f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables = new Drawable[origDr.length]; 553f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mNumChildren = orig.mNumChildren; 554f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 555f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures; 556f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDf != null) { 557f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = origDf.clone(); 558f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } else { 559f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren); 560f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 561f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 562f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 563f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 564f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDr[i] != null) { 565f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.put(i, new ConstantStateFuture(origDr[i])); 566f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 567f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = new Drawable[10]; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren = 0; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 573f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 576dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio return mChangingConfigurations | mChildrenChangingConfigurations; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int addChild(Drawable dr) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int pos = mNumChildren; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos >= mDrawables.length) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project growArray(pos, pos+10); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setVisible(false, true); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setCallback(mOwner); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables[pos] = dr; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren++; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations |= dr.getChangingConfigurations(); 592f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = false; 593f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = false; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantPadding = null; 5965140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy mPaddingChecked = false; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComputedConstantSize = false; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 60272146433322588c1116ee06c27ac758ad09d869cAlan Viverette final int getCapacity() { 60372146433322588c1116ee06c27ac758ad09d869cAlan Viverette return mDrawables.length; 60472146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 60572146433322588c1116ee06c27ac758ad09d869cAlan Viverette 606f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private final void createAllFutures() { 607f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 608f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int futureCount = mDrawableFutures.size(); 609f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { 610f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int index = mDrawableFutures.keyAt(keyIndex); 611f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this); 612f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 613f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 614f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = null; 615f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 616f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 617f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 61883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getChildCount() { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNumChildren; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62272146433322588c1116ee06c27ac758ad09d869cAlan Viverette /* 62372146433322588c1116ee06c27ac758ad09d869cAlan Viverette * @deprecated Use {@link #getChild} instead. 62472146433322588c1116ee06c27ac758ad09d869cAlan Viverette */ 62583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Drawable[] getChildren() { 626f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Create all futures for backwards compatibility. 627f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 628f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawables; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63272146433322588c1116ee06c27ac758ad09d869cAlan Viverette public final Drawable getChild(int index) { 633f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = mDrawables[index]; 634f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (result != null) { 635f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 636f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 637f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 638f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Prepare future drawable if necessary. 639f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 640f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int keyIndex = mDrawableFutures.indexOfKey(index); 641f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (keyIndex >= 0) { 642f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this); 643f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = prepared; 644f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.removeAt(keyIndex); 645f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return prepared; 646f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 647f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 648f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 649f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return null; 650f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 651f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 652f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final void setLayoutDirection(int layoutDirection) { 653f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 654f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // change layout direction when they are prepared. 655f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 656f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 657f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 658f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 659f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].setLayoutDirection(layoutDirection); 660f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 661f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 662f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 663f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = layoutDirection; 66472146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 66572146433322588c1116ee06c27ac758ad09d869cAlan Viverette 66672146433322588c1116ee06c27ac758ad09d869cAlan Viverette final void mutate() { 667f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 668f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // mutate when they are prepared. 669f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 67072146433322588c1116ee06c27ac758ad09d869cAlan Viverette final Drawable[] drawables = mDrawables; 67172146433322588c1116ee06c27ac758ad09d869cAlan Viverette for (int i = 0; i < N; i++) { 672f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 673f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].mutate(); 674f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 67572146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 676f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 677f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = true; 67872146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 67972146433322588c1116ee06c27ac758ad09d869cAlan Viverette 680f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 681f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * A boolean value indicating whether to use the maximum padding value 682f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * of all frames in the set (false), or to use the padding value of the 683f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * frame being shown (true). Default value is false. 684f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 68583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setVariablePadding(boolean variable) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = variable; 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Rect getConstantPadding() { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVariablePadding) { 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 693f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 694f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if ((mConstantPadding != null) || mPaddingChecked) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantPadding; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 698f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 699f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 7005140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy Rect r = null; 70183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Rect t = new Rect(); 702f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 70383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 70483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 70583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy if (drawables[i].getPadding(t)) { 7065140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy if (r == null) r = new Rect(0, 0, 0, 0); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.left > r.left) r.left = t.left; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.top > r.top) r.top = t.top; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.right > r.right) r.right = t.right; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.bottom > r.bottom) r.bottom = t.bottom; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 713f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 7145140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy mPaddingChecked = true; 7155140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy return (mConstantPadding = r); 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setConstantSize(boolean constant) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = constant; 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final boolean isConstantSize() { 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantSize; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantWidth() { 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantWidth; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 73483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantHeight() { 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantHeight; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumWidth() { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumWidth; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumHeight() { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumHeight; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne protected void computeConstantSize() { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComputedConstantSize = true; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 761f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 762f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 763f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 76483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 76578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne mConstantWidth = mConstantHeight = -1; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantMinimumWidth = mConstantMinimumHeight = 0; 76783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 768f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable dr = drawables[i]; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int s = dr.getIntrinsicWidth(); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantWidth) mConstantWidth = s; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getIntrinsicHeight(); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantHeight) mConstantHeight = s; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumWidth(); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumWidth) mConstantMinimumWidth = s; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumHeight(); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumHeight) mConstantMinimumHeight = s; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 780079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setEnterFadeDuration(int duration) { 781079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = duration; 782079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 783079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 784079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getEnterFadeDuration() { 785079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mEnterFadeDuration; 786079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 787079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 788079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setExitFadeDuration(int duration) { 789079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = duration; 790079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 791079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 792079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getExitFadeDuration() { 793079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mExitFadeDuration; 794079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 795079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 79683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getOpacity() { 797f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedOpacity) { 798f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mOpacity; 799f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 800f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 801f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 802f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 803f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = true; 804f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 805f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 80683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 807f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; 80883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 1; i < N; i++) { 80983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 811f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOpacity = op; 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return op; 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 81583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isStateful() { 817f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedStateful) { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateful; 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 820f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 821f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 822f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 823f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = true; 824f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 825f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 826f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 828f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].isStateful()) { 829f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = true; 830f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 833f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 834f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = false; 835f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 83883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public void growArray(int oldSize, int newSize) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable[] newDrawables = new Drawable[newSize]; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = newDrawables; 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized boolean canConstantState() { 845f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedConstantState) { 846f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mCanConstantState; 847f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 848f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 849f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 850f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 851f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 852f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 853f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 854f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 855f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 856f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].getConstantState() == null) { 857f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = false; 858f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 862f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 863f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 864f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 865f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 866f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 867f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * Class capable of cloning a Drawable from another Drawable's 868f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * ConstantState. 869f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 870f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private static class ConstantStateFuture { 871f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private final ConstantState mConstantState; 872f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 873f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private ConstantStateFuture(Drawable source) { 874f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantState = source.getConstantState(); 875f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 876f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 877f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 878f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * Obtains and prepares the Drawable represented by this future. 879f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * 880f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * @param state the container into which this future will be placed 881f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * @return a prepared Drawable 882f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 883f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette public Drawable get(DrawableContainerState state) { 884f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = (state.mRes == null) ? 885f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes); 886f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.setLayoutDirection(state.mLayoutDirection); 887f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.setCallback(state.mOwner); 888f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 889f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (state.mMutated) { 890f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.mutate(); 891f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 892f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 893f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 894f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 898f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette protected void setConstantState(DrawableContainerState state) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawableContainerState = state; 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 902