DrawableContainer.java revision f68bb66c6ec239790ba18b8d078eb7ab4894fdc3
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(); 91600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio boolean result = true; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r != null) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project padding.set(r); 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) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mColorFilter != cf) { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 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); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.setColorFilter(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 509c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, 510c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn Resources res) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwner = owner; 512f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mRes = res; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (orig != null) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = orig.mChangingConfigurations; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 518f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 519f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = orig.mVariablePadding; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = orig.mConstantSize; 523a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDither = orig.mDither; 524f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = orig.mMutated; 525f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = orig.mLayoutDirection; 526079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = orig.mEnterFadeDuration; 527079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = orig.mExitFadeDuration; 5283f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mAutoMirrored = orig.mAutoMirrored; 529079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 530f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Cloning the following values may require creating futures. 531f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantPadding = orig.getConstantPadding(); 532f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mPaddingChecked = true; 533f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 534f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantWidth = orig.getConstantWidth(); 535f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantHeight = orig.getConstantHeight(); 536f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantMinimumWidth = orig.getConstantMinimumWidth(); 537f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantMinimumHeight = orig.getConstantMinimumHeight(); 538f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mComputedConstantSize = true; 539f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 540f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mOpacity = orig.getOpacity(); 541f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = true; 542f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 543f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = orig.isStateful(); 544f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = true; 545f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 546f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Postpone cloning children and futures until we're absolutely 547f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // sure that we're done computing values for the original state. 548f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] origDr = orig.mDrawables; 549f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables = new Drawable[origDr.length]; 550f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mNumChildren = orig.mNumChildren; 551f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 552f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures; 553f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDf != null) { 554f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = origDf.clone(); 555f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } else { 556f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren); 557f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 558f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 559f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 560f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 561f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDr[i] != null) { 562f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.put(i, new ConstantStateFuture(origDr[i])); 563f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 564f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = new Drawable[10]; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren = 0; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 570f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 573dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio return mChangingConfigurations | mChildrenChangingConfigurations; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int addChild(Drawable dr) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int pos = mNumChildren; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos >= mDrawables.length) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project growArray(pos, pos+10); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setVisible(false, true); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setCallback(mOwner); 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables[pos] = dr; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren++; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations |= dr.getChangingConfigurations(); 589f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = false; 590f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = false; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantPadding = null; 5935140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy mPaddingChecked = false; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComputedConstantSize = false; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59972146433322588c1116ee06c27ac758ad09d869cAlan Viverette final int getCapacity() { 60072146433322588c1116ee06c27ac758ad09d869cAlan Viverette return mDrawables.length; 60172146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 60272146433322588c1116ee06c27ac758ad09d869cAlan Viverette 603f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private final void createAllFutures() { 604f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 605f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int futureCount = mDrawableFutures.size(); 606f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { 607f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int index = mDrawableFutures.keyAt(keyIndex); 608f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this); 609f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 610f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 611f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = null; 612f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 613f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 614f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 61583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getChildCount() { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNumChildren; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61972146433322588c1116ee06c27ac758ad09d869cAlan Viverette /* 62072146433322588c1116ee06c27ac758ad09d869cAlan Viverette * @deprecated Use {@link #getChild} instead. 62172146433322588c1116ee06c27ac758ad09d869cAlan Viverette */ 62283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Drawable[] getChildren() { 623f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Create all futures for backwards compatibility. 624f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 625f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawables; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62972146433322588c1116ee06c27ac758ad09d869cAlan Viverette public final Drawable getChild(int index) { 630f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = mDrawables[index]; 631f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (result != null) { 632f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 633f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 634f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 635f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Prepare future drawable if necessary. 636f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 637f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int keyIndex = mDrawableFutures.indexOfKey(index); 638f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (keyIndex >= 0) { 639f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this); 640f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = prepared; 641f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.removeAt(keyIndex); 642f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return prepared; 643f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 644f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 645f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 646f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return null; 647f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 648f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 649f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final void setLayoutDirection(int layoutDirection) { 650f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 651f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // change layout direction when they are prepared. 652f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 653f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 654f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 655f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 656f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].setLayoutDirection(layoutDirection); 657f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 658f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 659f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 660f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = layoutDirection; 66172146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 66272146433322588c1116ee06c27ac758ad09d869cAlan Viverette 66372146433322588c1116ee06c27ac758ad09d869cAlan Viverette final void mutate() { 664f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 665f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // mutate when they are prepared. 666f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 66772146433322588c1116ee06c27ac758ad09d869cAlan Viverette final Drawable[] drawables = mDrawables; 66872146433322588c1116ee06c27ac758ad09d869cAlan Viverette for (int i = 0; i < N; i++) { 669f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 670f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].mutate(); 671f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 67272146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 673f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 674f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = true; 67572146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 67672146433322588c1116ee06c27ac758ad09d869cAlan Viverette 677f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 678f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * A boolean value indicating whether to use the maximum padding value 679f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * of all frames in the set (false), or to use the padding value of the 680f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * frame being shown (true). Default value is false. 681f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 68283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setVariablePadding(boolean variable) { 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = variable; 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Rect getConstantPadding() { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVariablePadding) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 690f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 691f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if ((mConstantPadding != null) || mPaddingChecked) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantPadding; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 695f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 696f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 6975140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy Rect r = null; 69883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Rect t = new Rect(); 699f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 70083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 70183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 70283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy if (drawables[i].getPadding(t)) { 7035140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy if (r == null) r = new Rect(0, 0, 0, 0); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.left > r.left) r.left = t.left; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.top > r.top) r.top = t.top; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.right > r.right) r.right = t.right; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.bottom > r.bottom) r.bottom = t.bottom; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 710f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 7115140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy mPaddingChecked = true; 7125140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy return (mConstantPadding = r); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setConstantSize(boolean constant) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = constant; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final boolean isConstantSize() { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantSize; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantWidth() { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantWidth; 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 73183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantHeight() { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantHeight; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 73983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumWidth() { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumWidth; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumHeight() { 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mComputedConstantSize) { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumHeight; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 75578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne protected void computeConstantSize() { 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mComputedConstantSize = true; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 758f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 759f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 760f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 76183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 76278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne mConstantWidth = mConstantHeight = -1; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantMinimumWidth = mConstantMinimumHeight = 0; 76483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 765f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable dr = drawables[i]; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int s = dr.getIntrinsicWidth(); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantWidth) mConstantWidth = s; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getIntrinsicHeight(); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantHeight) mConstantHeight = s; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumWidth(); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumWidth) mConstantMinimumWidth = s; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumHeight(); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumHeight) mConstantMinimumHeight = s; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 777079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setEnterFadeDuration(int duration) { 778079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = duration; 779079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 780079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 781079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getEnterFadeDuration() { 782079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mEnterFadeDuration; 783079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 784079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 785079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setExitFadeDuration(int duration) { 786079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = duration; 787079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 788079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 789079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getExitFadeDuration() { 790079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mExitFadeDuration; 791079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 792079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 79383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getOpacity() { 794f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedOpacity) { 795f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mOpacity; 796f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 797f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 798f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 799f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 800f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = true; 801f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 802f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 80383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 804f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; 80583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 1; i < N; i++) { 80683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 808f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOpacity = op; 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return op; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 81283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isStateful() { 814f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedStateful) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateful; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 817f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 818f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 819f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 820f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = true; 821f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 822f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 823f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 825f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].isStateful()) { 826f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = true; 827f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 830f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 831f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mStateful = false; 832f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 83583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public void growArray(int oldSize, int newSize) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable[] newDrawables = new Drawable[newSize]; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = newDrawables; 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized boolean canConstantState() { 842f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedConstantState) { 843f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mCanConstantState; 844f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 845f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 846f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 847f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 848f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 849f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 850f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 851f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 852f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 853f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].getConstantState() == null) { 854f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = false; 855f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 860f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 861f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 862f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 863f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 864f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * Class capable of cloning a Drawable from another Drawable's 865f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * ConstantState. 866f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 867f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private static class ConstantStateFuture { 868f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private final ConstantState mConstantState; 869f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 870f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette private ConstantStateFuture(Drawable source) { 871f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantState = source.getConstantState(); 872f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 873f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 874f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 875f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * Obtains and prepares the Drawable represented by this future. 876f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * 877f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * @param state the container into which this future will be placed 878f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * @return a prepared Drawable 879f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 880f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette public Drawable get(DrawableContainerState state) { 881f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = (state.mRes == null) ? 882f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes); 883f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.setLayoutDirection(state.mLayoutDirection); 884f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.setCallback(state.mOwner); 885f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 886f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (state.mMutated) { 887f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette result.mutate(); 888f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 889f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 890f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 891f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 895f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette protected void setConstantState(DrawableContainerState state) { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawableContainerState = state; 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 899