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 private ColorFilter mColorFilter; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mCurIndex = -1; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Animations. 58079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private Runnable mAnimationRunnable; 59079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private long mEnterAnimationEnd; 60079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private long mExitAnimationEnd; 61079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private Drawable mLastDrawable; 62079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 63f68bb66c6ec239790ba18b8d078eb7ab4894fdc3John Spurlock private Insets mInsets = Insets.NONE; 64600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // overrides from Drawable 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.draw(canvas); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 72079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 73079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.draw(canvas); 74079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mDrawableContainerState.mChangingConfigurations 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mDrawableContainerState.mChildrenChangingConfigurations; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 83f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 84600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio private boolean needsMirroring() { 85600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 86600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 87600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect r = mDrawableContainerState.getConstantPadding(); 91f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio boolean result; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r != null) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project padding.set(r); 94f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio result = (r.left | r.top | r.bottom | r.right) != 0; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 96600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio if (mCurrDrawable != null) { 97600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio result = mCurrDrawable.getPadding(padding); 98600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } else { 99600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio result = super.getPadding(padding); 100600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 102600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio if (needsMirroring()) { 103600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio final int left = padding.left; 104600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio final int right = padding.right; 105600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio padding.left = right; 106600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio padding.right = left; 107600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 108600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return result; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1111557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne /** 1121557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne * @hide 1131557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne */ 1141557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne @Override 1157b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne public Insets getOpticalInsets() { 116600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return mInsets; 1171557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne } 1181557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAlpha != alpha) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlpha = alpha; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 124079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd == 0) { 1255f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(alpha); 126079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 127079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(false); 128079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 134b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 135b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mAlpha; 136b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 137b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 138b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 140a41581ed4033004c73115113f45b9844e9b0210fRomain Guy if (mDrawableContainerState.mDither != dither) { 141a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDrawableContainerState.mDither = dither; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1435f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setDither(mDrawableContainerState.mDither); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter cf) { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mColorFilter != cf) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColorFilter = cf; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1535f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setColorFilter(cf); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 157f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 158079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 159079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is entering 160079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 161079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 162079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 163079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setEnterFadeDuration(int ms) { 164079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mEnterFadeDuration = ms; 165079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 166f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 167079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 168079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is leaving 169079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 170079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 171079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 172079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setExitFadeDuration(int ms) { 173079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mExitFadeDuration = ms; 174079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 175f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 178079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 179079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setBounds(bounds); 180079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setBounds(bounds); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 185f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.isStateful(); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 190f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1923f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public void setAutoMirrored(boolean mirrored) { 1933f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mDrawableContainerState.mAutoMirrored = mirrored; 1943f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio if (mCurrDrawable != null) { 1953f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored); 1963f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 1973f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 1983f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 1993f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 2003f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public boolean isAutoMirrored() { 2013f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio return mDrawableContainerState.mAutoMirrored; 2023f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2033f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 2043f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 205079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void jumpToCurrentState() { 206079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean changed = false; 207079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 208079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.jumpToCurrentState(); 209079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 210079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 211079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 212079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 213079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.jumpToCurrentState(); 2145f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(mAlpha); 215079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 216079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 217079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 218079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 219079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 220079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 221079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 222079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 223079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 224079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (changed) { 225079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 226079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 227079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 228079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 229079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onStateChange(int[] state) { 231079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 232079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setState(state); 233079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setState(state); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onLevelChange(int level) { 242079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 243079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setLevel(level); 244079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setLevel(level); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantWidth(); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantHeight(); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 266f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumWidth() { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumWidth(); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumHeight() { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumHeight(); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28372146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 284079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void invalidateDrawable(Drawable who) { 285f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 286f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().invalidateDrawable(this); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29072146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 291079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void scheduleDrawable(Drawable who, Runnable what, long when) { 292f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 293f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().scheduleDrawable(this, what, when); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29772146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 298079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void unscheduleDrawable(Drawable who, Runnable what) { 299f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 300f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().unscheduleDrawable(this, what); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setVisible(boolean visible, boolean restart) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed = super.setVisible(visible, restart); 307079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 308079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(visible, restart); 309079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setVisible(visible, restart); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return changed; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 31883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT : 31983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy mDrawableContainerState.getOpacity(); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne public boolean selectDrawable(int idx) { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (idx == mCurIndex) { 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 326079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 327079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 328079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 329079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx 330079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + ": exit=" + mDrawableContainerState.mExitFadeDuration 331079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + " enter=" + mDrawableContainerState.mEnterFadeDuration); 332079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 333079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mExitFadeDuration > 0) { 334079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 335079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 336079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 338079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = mCurrDrawable; 339079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration; 340079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 341079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 342079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 344079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else if (mCurrDrawable != null) { 345079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.setVisible(false, false); 346079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 347079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 348079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) { 349f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable d = mDrawableContainerState.getChild(idx); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = d; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIndex = idx; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d != null) { 353600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio mInsets = d.getOpticalInsets(); 3545f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy d.mutate(); 355079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mEnterFadeDuration > 0) { 356079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration; 357079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 358079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn d.setAlpha(mAlpha); 359079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setVisible(isVisible(), true); 361a41581ed4033004c73115113f45b9844e9b0210fRomain Guy d.setDither(mDrawableContainerState.mDither); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setColorFilter(mColorFilter); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setState(getState()); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setLevel(getLevel()); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setBounds(getBounds()); 366731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio d.setLayoutDirection(getLayoutDirection()); 3673f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio d.setAutoMirrored(mDrawableContainerState.mAutoMirrored); 368600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } else { 369600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio mInsets = Insets.NONE; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = null; 373600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio mInsets = Insets.NONE; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIndex = -1; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 376079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 377079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) { 378079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mAnimationRunnable == null) { 379079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mAnimationRunnable = new Runnable() { 380079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override public void run() { 381079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 382079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 383079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 384079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn }; 385079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 386079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn unscheduleSelf(mAnimationRunnable); 387079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 388079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Compute first frame and schedule next animation. 389079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 390079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 391079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 393079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 396f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 397079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn void animate(boolean schedule) { 398079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 399079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean animating = false; 400079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 401079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 402079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd <= now) { 4035f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(mAlpha); 404079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 405079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 406079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mEnterAnimationEnd-now)*255) 407079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mEnterFadeDuration; 408079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha); 4095f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mCurrDrawable.mutate().setAlpha(((255-animAlpha)*mAlpha)/255); 410079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 411079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 412079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 413079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 414079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 415079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 416079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 417079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 418079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd <= now) { 419079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 420079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 421079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 422079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 423079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mExitAnimationEnd-now)*255) 424079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mExitFadeDuration; 425079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha); 4265f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mLastDrawable.mutate().setAlpha((animAlpha*mAlpha)/255); 427079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 428079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 429079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 430079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 431079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 432079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 433079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 434079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (schedule && animating) { 435079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn scheduleSelf(mAnimationRunnable, now + 1000/60); 436079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 437079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 438079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getCurrent() { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.canConstantState()) { 4476efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mDrawableContainerState.mChangingConfigurations = getChangingConfigurations(); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 45672146433322588c1116ee06c27ac758ad09d869cAlan Viverette mDrawableContainerState.mutate(); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne /** 46378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A ConstantState that can contain several {@link Drawable}s. 46478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * 46578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * This class was made public to enable testing, and its visibility may change in a future 46678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * release. 46778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */ 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract static class DrawableContainerState extends ConstantState { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DrawableContainer mOwner; 470f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Resources mRes; 471f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 472f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette SparseArray<ConstantStateFuture> mDrawableFutures; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 474f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mChangingConfigurations; 475f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mChildrenChangingConfigurations; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 477f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Drawable[] mDrawables; 478f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mNumChildren; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 480f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mVariablePadding; 481f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mPaddingChecked; 482f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Rect mConstantPadding; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 484f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mConstantSize; 485f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mComputedConstantSize; 486f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantWidth; 487f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantHeight; 488f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumWidth; 489f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumHeight; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 491f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedOpacity; 492f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mOpacity; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 494f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedStateful; 495f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mStateful; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 497f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedConstantState; 498f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCanConstantState; 4995140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy 500f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mDither = DEFAULT_DITHER; 501f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 502f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mMutated; 503f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mLayoutDirection; 504f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 505f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mEnterFadeDuration; 506f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mExitFadeDuration; 507079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 5083f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio boolean mAutoMirrored; 5093f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 510c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, 511c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn Resources res) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwner = owner; 513f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mRes = res; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (orig != null) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = orig.mChangingConfigurations; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 520f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = orig.mVariablePadding; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = orig.mConstantSize; 524a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDither = orig.mDither; 525f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = orig.mMutated; 526f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = orig.mLayoutDirection; 527079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = orig.mEnterFadeDuration; 528079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = orig.mExitFadeDuration; 5293f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mAutoMirrored = orig.mAutoMirrored; 530079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 531f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Cloning the following values may require creating futures. 532f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantPadding = orig.getConstantPadding(); 533f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mPaddingChecked = true; 534f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 535f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantWidth = orig.getConstantWidth(); 536f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantHeight = orig.getConstantHeight(); 537f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantMinimumWidth = orig.getConstantMinimumWidth(); 538f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantMinimumHeight = orig.getConstantMinimumHeight(); 539f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mComputedConstantSize = true; 540f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 541f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mOpacity = orig.getOpacity(); 542f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = true; 543f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 544f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = orig.isStateful(); 545f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = true; 546f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 547f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Postpone cloning children and futures until we're absolutely 548f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // sure that we're done computing values for the original state. 549f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] origDr = orig.mDrawables; 550f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables = new Drawable[origDr.length]; 551f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mNumChildren = orig.mNumChildren; 552f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 553f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures; 554f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDf != null) { 555f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = origDf.clone(); 556f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } else { 557f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren); 558f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 559f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 560f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 561f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 562f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDr[i] != null) { 563f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.put(i, new ConstantStateFuture(origDr[i])); 564f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 565f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = new Drawable[10]; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren = 0; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 571f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 574dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio return mChangingConfigurations | mChildrenChangingConfigurations; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int addChild(Drawable dr) { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int pos = mNumChildren; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos >= mDrawables.length) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project growArray(pos, pos+10); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setVisible(false, true); 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setCallback(mOwner); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables[pos] = dr; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren++; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations |= dr.getChangingConfigurations(); 590f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = false; 591f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = false; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantPadding = null; 5945140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy mPaddingChecked = false; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComputedConstantSize = false; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 60072146433322588c1116ee06c27ac758ad09d869cAlan Viverette final int getCapacity() { 60172146433322588c1116ee06c27ac758ad09d869cAlan Viverette return mDrawables.length; 60272146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 60372146433322588c1116ee06c27ac758ad09d869cAlan Viverette 604f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private final void createAllFutures() { 605f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 606f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int futureCount = mDrawableFutures.size(); 607f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { 608f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int index = mDrawableFutures.keyAt(keyIndex); 609f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this); 610f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 611f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 612f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = null; 613f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 614f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 615f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 61683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getChildCount() { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNumChildren; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62072146433322588c1116ee06c27ac758ad09d869cAlan Viverette /* 62172146433322588c1116ee06c27ac758ad09d869cAlan Viverette * @deprecated Use {@link #getChild} instead. 62272146433322588c1116ee06c27ac758ad09d869cAlan Viverette */ 62383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Drawable[] getChildren() { 624f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Create all futures for backwards compatibility. 625f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 626f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawables; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63072146433322588c1116ee06c27ac758ad09d869cAlan Viverette public final Drawable getChild(int index) { 631f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = mDrawables[index]; 632f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (result != null) { 633f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 634f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 635f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 636f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Prepare future drawable if necessary. 637f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 638f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int keyIndex = mDrawableFutures.indexOfKey(index); 639f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (keyIndex >= 0) { 640f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this); 641f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = prepared; 642f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.removeAt(keyIndex); 643f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return prepared; 644f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 645f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 646f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 647f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return null; 648f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 649f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 650f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final void setLayoutDirection(int layoutDirection) { 651f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 652f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // change layout direction when they are prepared. 653f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 654f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 655f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 656f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 657f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].setLayoutDirection(layoutDirection); 658f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 659f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 660f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 661f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = layoutDirection; 66272146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 66372146433322588c1116ee06c27ac758ad09d869cAlan Viverette 66472146433322588c1116ee06c27ac758ad09d869cAlan Viverette final void mutate() { 665f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 666f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // mutate when they are prepared. 667f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 66872146433322588c1116ee06c27ac758ad09d869cAlan Viverette final Drawable[] drawables = mDrawables; 66972146433322588c1116ee06c27ac758ad09d869cAlan Viverette for (int i = 0; i < N; i++) { 670f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 671f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].mutate(); 672f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 67372146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 674f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 675f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = true; 67672146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 67772146433322588c1116ee06c27ac758ad09d869cAlan Viverette 678f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 679f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * A boolean value indicating whether to use the maximum padding value 680f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * of all frames in the set (false), or to use the padding value of the 681f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * frame being shown (true). Default value is false. 682f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 68383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setVariablePadding(boolean variable) { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = variable; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Rect getConstantPadding() { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVariablePadding) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 691f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 692f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if ((mConstantPadding != null) || mPaddingChecked) { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantPadding; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 696f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 697f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 6985140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy Rect r = null; 69983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Rect t = new Rect(); 700f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 70183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 70283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 70383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy if (drawables[i].getPadding(t)) { 7045140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy if (r == null) r = new Rect(0, 0, 0, 0); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.left > r.left) r.left = t.left; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.top > r.top) r.top = t.top; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.right > r.right) r.right = t.right; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.bottom > r.bottom) r.bottom = t.bottom; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 711f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 7125140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy mPaddingChecked = true; 7135140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy return (mConstantPadding = r); 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setConstantSize(boolean constant) { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = constant; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final boolean isConstantSize() { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantSize; 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantWidth() { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantWidth; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 73283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantHeight() { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantHeight; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumWidth() { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumWidth; 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumHeight() { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumHeight; 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne protected void computeConstantSize() { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComputedConstantSize = true; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 760f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 761f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 76283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 76378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne mConstantWidth = mConstantHeight = -1; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantMinimumWidth = mConstantMinimumHeight = 0; 76583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 766f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable dr = drawables[i]; 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int s = dr.getIntrinsicWidth(); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantWidth) mConstantWidth = s; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getIntrinsicHeight(); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantHeight) mConstantHeight = s; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumWidth(); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumWidth) mConstantMinimumWidth = s; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumHeight(); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumHeight) mConstantMinimumHeight = s; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 778079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setEnterFadeDuration(int duration) { 779079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = duration; 780079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 781079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 782079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getEnterFadeDuration() { 783079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mEnterFadeDuration; 784079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 785079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 786079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setExitFadeDuration(int duration) { 787079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = duration; 788079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 789079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 790079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getExitFadeDuration() { 791079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mExitFadeDuration; 792079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 793079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 79483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getOpacity() { 795f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedOpacity) { 796f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mOpacity; 797f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 798f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 799f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 800f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 801f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = true; 802f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 803f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 80483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 805f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; 80683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 1; i < N; i++) { 80783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 809f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOpacity = op; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return op; 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 81383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isStateful() { 815f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedStateful) { 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateful; 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 818f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 819f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 820f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 821f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = true; 822f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 823f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 824f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 826f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].isStateful()) { 827f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = true; 828f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 831f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 832f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = false; 833f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 83683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public void growArray(int oldSize, int newSize) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable[] newDrawables = new Drawable[newSize]; 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = newDrawables; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized boolean canConstantState() { 843f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedConstantState) { 844f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mCanConstantState; 845f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 846f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 847f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 848f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 849f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 850f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 851f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 852f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 853f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 854f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].getConstantState() == null) { 855f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = false; 856f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 860f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 861f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 862f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 863f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 864f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 865f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * Class capable of cloning a Drawable from another Drawable's 866f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * ConstantState. 867f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 868f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private static class ConstantStateFuture { 869f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private final ConstantState mConstantState; 870f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 871f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private ConstantStateFuture(Drawable source) { 872f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantState = source.getConstantState(); 873f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 874f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 875f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 876f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * Obtains and prepares the Drawable represented by this future. 877f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * 878f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * @param state the container into which this future will be placed 879f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * @return a prepared Drawable 880f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 881f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette public Drawable get(DrawableContainerState state) { 882f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = (state.mRes == null) ? 883f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes); 884f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.setLayoutDirection(state.mLayoutDirection); 885f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.setCallback(state.mOwner); 886f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 887f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (state.mMutated) { 888f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.mutate(); 889f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 890f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 891f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 892f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 896f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette protected void setConstantState(DrawableContainerState state) { 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawableContainerState = state; 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 900