DrawableContainer.java revision f380072eeffdb5f993e5bd1c31571afe11d1a82e
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 1958945975b256739fdfe78435d7846d1e2fd29da1Chris Craikimport android.annotation.NonNull; 20ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viveretteimport android.content.pm.ActivityInfo.Config; 21b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 22c2974809373697147cbe5754835cc871fb93aef1Dianne Hackbornimport android.content.res.Resources; 2352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme; 2478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Canvas; 2578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.ColorFilter; 26bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milneimport android.graphics.Insets; 2758945975b256739fdfe78435d7846d1e2fd29da1Chris Craikimport android.graphics.Outline; 2878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PixelFormat; 29b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 300c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhuimport android.graphics.Rect; 31079e23575024e103358c982152afb7a720ae1a8aDianne Hackbornimport android.os.SystemClock; 32f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viveretteimport android.util.DisplayMetrics; 33600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglioimport android.util.LayoutDirection; 34f390f770ee570f1f4def41b165cb9492e381be40Alan Viveretteimport android.util.SparseArray; 35dfa4646eca54511a28f2c61e1f4b9c697e05a913Alan Viveretteimport android.view.View; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne/** 3878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A helper class that contains several {@link Drawable}s and selects which one to use. 3978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * 4078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * You can subclass it to create your own DrawableContainers or directly use one its child classes. 4178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DrawableContainer extends Drawable implements Drawable.Callback { 43079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private static final boolean DEBUG = false; 44079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private static final String TAG = "DrawableContainer"; 45211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed 46211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed /** 47211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * To be proper, we should have a getter for dither (and alpha, etc.) 48211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * so that proxy classes like this can save/restore their delegates' 49211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * values, but we don't have getters. Since we do have setters 50211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * (e.g. setDither), which this proxy forwards on, we have to have some 51211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * default/initial setting. 52211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * 53211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * The initial setting for dither is now true, since it almost always seems 54211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed * to improve the quality at negligible cost. 55211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed */ 56211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed private static final boolean DEFAULT_DITHER = true; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private DrawableContainerState mDrawableContainerState; 587068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette private Rect mHotspotBounds; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mCurrDrawable; 60ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette private Drawable mLastDrawable; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mAlpha = 0xFF; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette /** Whether setAlpha() has been called at least once. */ 64729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette private boolean mHasAlpha; 65729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mCurIndex = -1; 67ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette private int mLastIndex = -1; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Animations. 71079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private Runnable mAnimationRunnable; 72079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private long mEnterAnimationEnd; 73079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn private long mExitAnimationEnd; 74079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 756d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette /** Callback that blocks invalidation. Used for drawable initialization. */ 766d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette private BlockInvalidateCallback mBlockInvalidateCallback; 776d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // overrides from Drawable 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.draw(canvas); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 85079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 86079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.draw(canvas); 87079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 91ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() 93e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | mDrawableContainerState.getChangingConfigurations(); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 95f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 96600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio private boolean needsMirroring() { 97600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 98600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 99600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect r = mDrawableContainerState.getConstantPadding(); 103f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio boolean result; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r != null) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project padding.set(r); 106f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio result = (r.left | r.top | r.bottom | r.right) != 0; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 108600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio if (mCurrDrawable != null) { 109600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio result = mCurrDrawable.getPadding(padding); 110600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } else { 111600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio result = super.getPadding(padding); 112600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 114600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio if (needsMirroring()) { 115600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio final int left = padding.left; 116600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio final int right = padding.right; 117600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio padding.left = right; 118600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio padding.right = left; 119600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio } 120600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio return result; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1231557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne /** 1241557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne * @hide 1251557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne */ 1261557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne @Override 1277b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne public Insets getOpticalInsets() { 1288de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette if (mCurrDrawable != null) { 1298de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette return mCurrDrawable.getOpticalInsets(); 1308de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette } 1318de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette return Insets.NONE; 1321557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne } 1331557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13531ba192dd201df2cad96a8c503f730130ab0d80fChris Craik public void getOutline(@NonNull Outline outline) { 13658945975b256739fdfe78435d7846d1e2fd29da1Chris Craik if (mCurrDrawable != null) { 13731ba192dd201df2cad96a8c503f730130ab0d80fChris Craik mCurrDrawable.getOutline(outline); 13858945975b256739fdfe78435d7846d1e2fd29da1Chris Craik } 13958945975b256739fdfe78435d7846d1e2fd29da1Chris Craik } 14058945975b256739fdfe78435d7846d1e2fd29da1Chris Craik 14158945975b256739fdfe78435d7846d1e2fd29da1Chris Craik @Override 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 14334bd56b546bce47422a430d9d7806dc3cb4254bfAlan Viverette if (!mHasAlpha || mAlpha != alpha) { 14434bd56b546bce47422a430d9d7806dc3cb4254bfAlan Viverette mHasAlpha = true; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlpha = alpha; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 147079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd == 0) { 1489b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(alpha); 149079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 150079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(false); 151079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 157b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 158b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mAlpha; 159b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 160b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 161b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 163a41581ed4033004c73115113f45b9844e9b0210fRomain Guy if (mDrawableContainerState.mDither != dither) { 164a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDrawableContainerState.mDither = dither; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1669b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setDither(mDrawableContainerState.mDither); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 172bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik public void setColorFilter(ColorFilter colorFilter) { 1736f51440a746ef4925ec329cd3a71a9689be2b10bAlan Viverette mDrawableContainerState.mHasColorFilter = true; 174729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette 175bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik if (mDrawableContainerState.mColorFilter != colorFilter) { 176bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mDrawableContainerState.mColorFilter = colorFilter; 177729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 1799b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setColorFilter(colorFilter); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 183f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 184b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 185a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintList(ColorStateList tint) { 186bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mDrawableContainerState.mHasTintList = true; 187b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 188bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette if (mDrawableContainerState.mTintList != tint) { 189bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mDrawableContainerState.mTintList = tint; 190a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette 191a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (mCurrDrawable != null) { 1929b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setTintList(tint); 193a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 194a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 195a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 196a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette 197a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette @Override 198a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintMode(Mode tintMode) { 199bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mDrawableContainerState.mHasTintMode = true; 200a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette 201a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (mDrawableContainerState.mTintMode != tintMode) { 202b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mDrawableContainerState.mTintMode = tintMode; 203b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 204b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (mCurrDrawable != null) { 2059b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setTintMode(tintMode); 206b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 207b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 208b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 209b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 210079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 211079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is entering 212079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 213079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 214079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 215079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setEnterFadeDuration(int ms) { 216079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mEnterFadeDuration = ms; 217079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 218f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 219079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 220079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is leaving 221079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 222079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 223079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 224079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setExitFadeDuration(int ms) { 225079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mExitFadeDuration = ms; 226079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 227f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 230079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 231079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setBounds(bounds); 232079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setBounds(bounds); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 237f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.isStateful(); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 242f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 243f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He /** @hide */ 244f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He @Override 245f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He public boolean hasFocusStateSpecified() { 246f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He if (mCurrDrawable != null) { 247f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He return mCurrDrawable.hasFocusStateSpecified(); 248f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He } 249f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He if (mLastDrawable != null) { 250f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He return mLastDrawable.hasFocusStateSpecified(); 251f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He } 252f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He return false; 253f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He } 254f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2563f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public void setAutoMirrored(boolean mirrored) { 257729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette if (mDrawableContainerState.mAutoMirrored != mirrored) { 258729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette mDrawableContainerState.mAutoMirrored = mirrored; 259729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette if (mCurrDrawable != null) { 2609b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAutoMirrored(mDrawableContainerState.mAutoMirrored); 261729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette } 2623f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2633f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2643f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 2653f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 2663f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public boolean isAutoMirrored() { 2673f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio return mDrawableContainerState.mAutoMirrored; 2683f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2693f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 2703f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 271079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void jumpToCurrentState() { 272079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean changed = false; 273079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 274079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.jumpToCurrentState(); 275079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 276ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = -1; 277079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 278079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 279079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 280079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.jumpToCurrentState(); 281729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette if (mHasAlpha) { 2829b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(mAlpha); 283729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette } 284079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 285079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 286079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 287079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 288079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 289079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 290079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 291079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 292079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 293079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (changed) { 294079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 295079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 296079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 297079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 298079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override 299c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette public void setHotspot(float x, float y) { 300307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette if (mCurrDrawable != null) { 301c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette mCurrDrawable.setHotspot(x, y); 302307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette } 303307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette } 304307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette 305307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette @Override 30653a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette public void setHotspotBounds(int left, int top, int right, int bottom) { 3077068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette if (mHotspotBounds == null) { 30827cf86939d918b2d6b32a0650a48b8a2afaa26b6Alexander Martinz mHotspotBounds = new Rect(left, top, right, bottom); 3097068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } else { 31027cf86939d918b2d6b32a0650a48b8a2afaa26b6Alexander Martinz mHotspotBounds.set(left, top, right, bottom); 3117068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 3127068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette 31353a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette if (mCurrDrawable != null) { 31453a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette mCurrDrawable.setHotspotBounds(left, top, right, bottom); 31553a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette } 31653a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette } 31753a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette 3187068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette @Override 3197068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette public void getHotspotBounds(Rect outRect) { 3207068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette if (mHotspotBounds != null) { 3217068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette outRect.set(mHotspotBounds); 3227068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } else { 3237068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette super.getHotspotBounds(outRect); 3247068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 3257068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 3267068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette 32753a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette @Override 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onStateChange(int[] state) { 329079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 330079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setState(state); 331079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setState(state); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3390b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette protected boolean onLevelChange(int level) { 340079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 341079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setLevel(level); 342079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setLevel(level); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 350dfa4646eca54511a28f2c61e1f4b9c697e05a913Alan Viverette public boolean onLayoutDirectionChanged(@View.ResolvedLayoutDir int layoutDirection) { 351a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Let the container handle setting its own layout direction. Otherwise, 352a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // we're accessing potentially unused states. 353a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawableContainerState.setLayoutDirection(layoutDirection, getCurrentIndex()); 354a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 355a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 356a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantWidth(); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantHeight(); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 371f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumWidth() { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumWidth(); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumHeight() { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumHeight(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38872146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 389f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void invalidateDrawable(@NonNull Drawable who) { 390f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 391f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().invalidateDrawable(this); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39572146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 396f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { 397f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 398f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().scheduleDrawable(this, what, when); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40272146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 403f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { 404f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 405f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().unscheduleDrawable(this, what); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setVisible(boolean visible, boolean restart) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed = super.setVisible(visible, restart); 412079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 413079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(visible, restart); 414079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setVisible(visible, restart); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return changed; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 42383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT : 42483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy mDrawableContainerState.getOpacity(); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4275e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette /** @hide */ 4285e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette public void setCurrentIndex(int index) { 4295e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette selectDrawable(index); 4305e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette } 4315e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette 4325e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette /** @hide */ 4335e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette public int getCurrentIndex() { 4345e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette return mCurIndex; 4355e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette } 4365e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette 437a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette /** 438a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * Sets the currently displayed drawable by index. 439a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * <p> 440a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * If an invalid index is specified, the current drawable will be set to 441a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * {@code null} and the index will be set to {@code -1}. 442a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * 443a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * @param index the index of the drawable to display 444a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * @return {@code true} if the drawable changed, {@code false} otherwise 445a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette */ 446a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette public boolean selectDrawable(int index) { 447a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette if (index == mCurIndex) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 450079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 451079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 452079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 453a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + index 454079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + ": exit=" + mDrawableContainerState.mExitFadeDuration 455079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + " enter=" + mDrawableContainerState.mEnterFadeDuration); 456079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 457079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mExitFadeDuration > 0) { 458079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 459079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 460079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 462079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = mCurrDrawable; 463ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = mCurIndex; 464079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration; 465079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 466079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 467ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = -1; 468079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 470079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else if (mCurrDrawable != null) { 471079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.setVisible(false, false); 472079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 473079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 474a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette if (index >= 0 && index < mDrawableContainerState.mNumChildren) { 475a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette final Drawable d = mDrawableContainerState.getChild(index); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = d; 477a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette mCurIndex = index; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d != null) { 479079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mEnterFadeDuration > 0) { 480079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration; 4817068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 482419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette initializeDrawableForDisplay(d); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = null; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIndex = -1; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 488079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 489079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) { 490079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mAnimationRunnable == null) { 491079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mAnimationRunnable = new Runnable() { 492079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override public void run() { 493079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 494079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 495079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 496079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn }; 497079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 498079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn unscheduleSelf(mAnimationRunnable); 499079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 500079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Compute first frame and schedule next animation. 501079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 502079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 503079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 505079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 508f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 509419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette /** 510419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette * Initializes a drawable for display in this container. 511419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette * 512419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette * @param d The drawable to initialize. 513419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette */ 514419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette private void initializeDrawableForDisplay(Drawable d) { 5156d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette if (mBlockInvalidateCallback == null) { 5166d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mBlockInvalidateCallback = new BlockInvalidateCallback(); 5176d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 5186d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 5192b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // Temporary fix for suspending callbacks during initialization. We 5202b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // don't want any of these setters causing an invalidate() since that 5212b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // may call back into DrawableContainer. 5226d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette d.setCallback(mBlockInvalidateCallback.wrap(d.getCallback())); 5232b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette 5242b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette try { 5252b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mEnterFadeDuration <= 0 && mHasAlpha) { 5262b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setAlpha(mAlpha); 527419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 528419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 5292b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mHasColorFilter) { 5302b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // Color filter always overrides tint. 5312b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setColorFilter(mDrawableContainerState.mColorFilter); 5322b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } else { 5332b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mHasTintList) { 5342b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setTintList(mDrawableContainerState.mTintList); 5352b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 5362b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mHasTintMode) { 5372b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setTintMode(mDrawableContainerState.mTintMode); 5382b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 5392b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 540419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 5412b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setVisible(isVisible(), true); 5422b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setDither(mDrawableContainerState.mDither); 5432b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setState(getState()); 5442b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setLevel(getLevel()); 5452b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setBounds(getBounds()); 5462b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setLayoutDirection(getLayoutDirection()); 5472b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setAutoMirrored(mDrawableContainerState.mAutoMirrored); 5482b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette 5492b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette final Rect hotspotBounds = mHotspotBounds; 5502b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (hotspotBounds != null) { 5512b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top, 5522b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette hotspotBounds.right, hotspotBounds.bottom); 5532b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 5542b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } finally { 5556d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette d.setCallback(mBlockInvalidateCallback.unwrap()); 556419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 557419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 558419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 559079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn void animate(boolean schedule) { 560729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette mHasAlpha = true; 561729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette 562079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 563079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean animating = false; 564079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 565079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 566079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd <= now) { 5679b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(mAlpha); 568079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 569079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 570079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mEnterAnimationEnd-now)*255) 571079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mEnterFadeDuration; 5729b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(((255-animAlpha)*mAlpha)/255); 573079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 574079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 575079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 576079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 577079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 578079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 579079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 580079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 581079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd <= now) { 582079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 583079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 584ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = -1; 585079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 586079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 587079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mExitAnimationEnd-now)*255) 588079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mExitFadeDuration; 5899b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mLastDrawable.setAlpha((animAlpha*mAlpha)/255); 590079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 591079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 592079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 593079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 594079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 595079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 596079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 597079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (schedule && animating) { 5988dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette scheduleSelf(mAnimationRunnable, now + 1000 / 60); 599079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 600079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 601079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getCurrent() { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 607f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette /** 608f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * Updates the source density based on the resources used to inflate 609f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * density-dependent values. Implementing classes should call this method 610f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * during inflation. 611f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * 612f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * @param res the resources used to inflate density-dependent values 6130c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu * @hide 614f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette */ 6150c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu protected final void updateDensity(Resources res) { 616f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mDrawableContainerState.updateDensity(res); 617f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 618f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 62052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void applyTheme(Theme theme) { 62152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mDrawableContainerState.applyTheme(theme); 62252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 62352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 62452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 62552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 62652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return mDrawableContainerState.canApplyTheme(); 62752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 62852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 62952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.canConstantState()) { 6326efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mDrawableContainerState.mChangingConfigurations = getChangingConfigurations(); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState; 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 6415ed8f27858dbdf85203068eca46eef0a65f3344eAlan Viverette final DrawableContainerState clone = cloneConstantState(); 6425ed8f27858dbdf85203068eca46eef0a65f3344eAlan Viverette clone.mutate(); 6435ed8f27858dbdf85203068eca46eef0a65f3344eAlan Viverette setConstantState(clone); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne /** 6508dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * Returns a shallow copy of the container's constant state to be used as 6518dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * the base state for {@link #mutate()}. 6528dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * 6538dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * @return a shallow copy of the constant state 6548dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette */ 6558dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette DrawableContainerState cloneConstantState() { 6568dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette return mDrawableContainerState; 6578dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette } 6588dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette 6598dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette /** 660727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 661727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 662727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 663727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 664727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mDrawableContainerState.clearMutated(); 665727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 666727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 667727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 668727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 66978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A ConstantState that can contain several {@link Drawable}s. 67078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * 67178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * This class was made public to enable testing, and its visibility may change in a future 67278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * release. 67378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */ 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract static class DrawableContainerState extends ConstantState { 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DrawableContainer mOwner; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 677f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette Resources mSourceRes; 678f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette int mDensity = DisplayMetrics.DENSITY_DEFAULT; 679ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette @Config int mChangingConfigurations; 680ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette @Config int mChildrenChangingConfigurations; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6821259f616c26f89dd5000745d7c364fae41b23682Alan Viverette SparseArray<ConstantState> mDrawableFutures; 683f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Drawable[] mDrawables; 684f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mNumChildren; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 686d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette boolean mVariablePadding = false; 687f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette boolean mCheckedPadding; 688f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Rect mConstantPadding; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 690d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette boolean mConstantSize = false; 691f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette boolean mCheckedConstantSize; 692f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantWidth; 693f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantHeight; 694f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumWidth; 695f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumHeight; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 697f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedOpacity; 698f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mOpacity; 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 700f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedStateful; 701f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mStateful; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 703f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedConstantState; 704f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCanConstantState; 7055140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy 706f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mDither = DEFAULT_DITHER; 707f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 708f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mMutated; 709f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mLayoutDirection; 710f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 711d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette int mEnterFadeDuration = 0; 712d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette int mExitFadeDuration = 0; 713079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 7143f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio boolean mAutoMirrored; 7153f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 716d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette ColorFilter mColorFilter; 717729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette boolean mHasColorFilter; 718d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette 719bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette ColorStateList mTintList; 720b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette Mode mTintMode; 721bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette boolean mHasTintList; 722bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette boolean mHasTintMode; 723b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 7240c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu /** 7250c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu * @hide 7260c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu */ 7270c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu protected DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, 728c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn Resources res) { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwner = owner; 730ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mSourceRes = res != null ? res : (orig != null ? orig.mSourceRes : null); 731ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDensity = Drawable.resolveDensity(res, orig != null ? orig.mDensity : 0); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (orig != null) { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = orig.mChangingConfigurations; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 737f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 738f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = orig.mVariablePadding; 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = orig.mConstantSize; 742a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDither = orig.mDither; 743f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = orig.mMutated; 744f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = orig.mLayoutDirection; 745079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = orig.mEnterFadeDuration; 746079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = orig.mExitFadeDuration; 7473f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mAutoMirrored = orig.mAutoMirrored; 748d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette mColorFilter = orig.mColorFilter; 749729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette mHasColorFilter = orig.mHasColorFilter; 750bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mTintList = orig.mTintList; 751b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = orig.mTintMode; 752bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mHasTintList = orig.mHasTintList; 753bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mHasTintMode = orig.mHasTintMode; 754079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 755ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mDensity == mDensity) { 756f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedPadding) { 757f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantPadding = new Rect(orig.mConstantPadding); 758f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedPadding = true; 759f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 760f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 761f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedConstantSize) { 762f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantWidth = orig.mConstantWidth; 763f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantHeight = orig.mConstantHeight; 764f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantMinimumWidth = orig.mConstantMinimumWidth; 765f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantMinimumHeight = orig.mConstantMinimumHeight; 766f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedConstantSize = true; 767f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 768f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 769f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 770f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedOpacity) { 771f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mOpacity = orig.mOpacity; 772f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedOpacity = true; 773f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 774f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 775f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedStateful) { 776f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mStateful = orig.mStateful; 777f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedStateful = true; 778f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 779f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 780f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Postpone cloning children and futures until we're absolutely 781f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // sure that we're done computing values for the original state. 782f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] origDr = orig.mDrawables; 783f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables = new Drawable[origDr.length]; 784f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mNumChildren = orig.mNumChildren; 785f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 7861259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final SparseArray<ConstantState> origDf = orig.mDrawableFutures; 787f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDf != null) { 788f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = origDf.clone(); 789f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } else { 79006ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette mDrawableFutures = new SparseArray<>(mNumChildren); 791f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 792f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 79362b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette // Create futures for drawables with constant states. If a 79462b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette // drawable doesn't have a constant state, then we can't clone 79562b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette // it and we'll have to reference the original. 796f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 797f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 798f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDr[i] != null) { 7991259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState cs = origDr[i].getConstantState(); 8001259f616c26f89dd5000745d7c364fae41b23682Alan Viverette if (cs != null) { 8011259f616c26f89dd5000745d7c364fae41b23682Alan Viverette mDrawableFutures.put(i, cs); 80262b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette } else { 80362b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette mDrawables[i] = origDr[i]; 80462b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette } 805f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 806f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = new Drawable[10]; 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren = 0; 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 812f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 814ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 815dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio return mChangingConfigurations | mChildrenChangingConfigurations; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 818a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette /** 819a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * Adds the drawable to the end of the list of contained drawables. 820a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * 821a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * @param dr the drawable to add 822a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * @return the position of the drawable within the container 823a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette */ 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int addChild(Drawable dr) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int pos = mNumChildren; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos >= mDrawables.length) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project growArray(pos, pos+10); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 830a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette dr.mutate(); 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setVisible(false, true); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setCallback(mOwner); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables[pos] = dr; 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren++; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations |= dr.getChangingConfigurations(); 837f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedStateful = false; 838f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedOpacity = false; 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantPadding = null; 841f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedPadding = false; 842f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedConstantSize = false; 8435291a9571580d5147331adbdefb017fa395df505Alan Viverette mCheckedConstantState = false; 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84872146433322588c1116ee06c27ac758ad09d869cAlan Viverette final int getCapacity() { 84972146433322588c1116ee06c27ac758ad09d869cAlan Viverette return mDrawables.length; 85072146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 85172146433322588c1116ee06c27ac758ad09d869cAlan Viverette 8521259f616c26f89dd5000745d7c364fae41b23682Alan Viverette private void createAllFutures() { 853f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 854f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int futureCount = mDrawableFutures.size(); 855f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { 856f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int index = mDrawableFutures.keyAt(keyIndex); 8571259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState cs = mDrawableFutures.valueAt(keyIndex); 8581259f616c26f89dd5000745d7c364fae41b23682Alan Viverette mDrawables[index] = prepareDrawable(cs.newDrawable(mSourceRes)); 859f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 860f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 861f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = null; 862f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 863f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 864f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8651259f616c26f89dd5000745d7c364fae41b23682Alan Viverette private Drawable prepareDrawable(Drawable child) { 8661259f616c26f89dd5000745d7c364fae41b23682Alan Viverette child.setLayoutDirection(mLayoutDirection); 8679b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette child = child.mutate(); 868b46ba3b2b0268688852cdf3d1fb4afe4873d63beAlan Viverette child.setCallback(mOwner); 8691259f616c26f89dd5000745d7c364fae41b23682Alan Viverette return child; 8701259f616c26f89dd5000745d7c364fae41b23682Alan Viverette } 8711259f616c26f89dd5000745d7c364fae41b23682Alan Viverette 87283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getChildCount() { 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNumChildren; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 87672146433322588c1116ee06c27ac758ad09d869cAlan Viverette /* 87772146433322588c1116ee06c27ac758ad09d869cAlan Viverette * @deprecated Use {@link #getChild} instead. 87872146433322588c1116ee06c27ac758ad09d869cAlan Viverette */ 87983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Drawable[] getChildren() { 880f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Create all futures for backwards compatibility. 881f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 882f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawables; 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 88672146433322588c1116ee06c27ac758ad09d869cAlan Viverette public final Drawable getChild(int index) { 887f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = mDrawables[index]; 888f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (result != null) { 889f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 890f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 891f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 892f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Prepare future drawable if necessary. 893f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 894f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int keyIndex = mDrawableFutures.indexOfKey(index); 895f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (keyIndex >= 0) { 8961259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState cs = mDrawableFutures.valueAt(keyIndex); 8971259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final Drawable prepared = prepareDrawable(cs.newDrawable(mSourceRes)); 898f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = prepared; 899f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.removeAt(keyIndex); 90006ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette if (mDrawableFutures.size() == 0) { 90106ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette mDrawableFutures = null; 90206ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette } 903f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return prepared; 904f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 905f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 906f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 907f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return null; 908f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 909f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 910a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean setLayoutDirection(int layoutDirection, int currentIndex) { 911a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette boolean changed = false; 912a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 913f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 914f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // change layout direction when they are prepared. 915f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 916f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 917f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 918f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 919a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean childChanged = drawables[i].setLayoutDirection(layoutDirection); 920a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (i == currentIndex) { 921a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette changed = childChanged; 922a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 923f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 924f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 925f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 926f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = layoutDirection; 927a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 928a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return changed; 92972146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 93072146433322588c1116ee06c27ac758ad09d869cAlan Viverette 931f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette /** 932f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * Updates the source density based on the resources used to inflate 933f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * density-dependent values. 934f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * 935f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * @param res the resources used to inflate density-dependent values 936f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette */ 937f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette final void updateDensity(Resources res) { 9382d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette if (res != null) { 939f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mSourceRes = res; 940f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 9412d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette // The density may have changed since the last update (if any). Any 9422d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette // dimension-type attributes will need their default values scaled. 9432d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette final int targetDensity = Drawable.resolveDensity(res, mDensity); 9442d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette final int sourceDensity = mDensity; 9452d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette mDensity = targetDensity; 946f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 9472d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette if (sourceDensity != targetDensity) { 9482d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette mCheckedConstantSize = false; 9492d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette mCheckedPadding = false; 9502d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette } 951f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 952f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 953f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 95452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final void applyTheme(Theme theme) { 95517cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (theme != null) { 95617cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette createAllFutures(); 95717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette 95817cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final int N = mNumChildren; 95917cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final Drawable[] drawables = mDrawables; 96017cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette for (int i = 0; i < N; i++) { 96117cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (drawables[i] != null && drawables[i].canApplyTheme()) { 96217cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette drawables[i].applyTheme(theme); 963e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 964e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette // Update cached mask of child changing configurations. 965e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mChildrenChangingConfigurations |= drawables[i].getChangingConfigurations(); 96617cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette } 96752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 968f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 969f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette updateDensity(theme.getResources()); 97052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 97152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 97252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 97352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 97452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 97552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int N = mNumChildren; 97652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final Drawable[] drawables = mDrawables; 97752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette for (int i = 0; i < N; i++) { 978b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final Drawable d = drawables[i]; 97952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (d != null) { 98052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (d.canApplyTheme()) { 98152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return true; 98252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 98352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 9841259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState future = mDrawableFutures.get(i); 98552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (future != null && future.canApplyTheme()) { 98652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return true; 98752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 98852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 98952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 99052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 99152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return false; 99252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 99352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 9948dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette private void mutate() { 995f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 996f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // mutate when they are prepared. 997f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 99872146433322588c1116ee06c27ac758ad09d869cAlan Viverette final Drawable[] drawables = mDrawables; 99972146433322588c1116ee06c27ac758ad09d869cAlan Viverette for (int i = 0; i < N; i++) { 1000f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 1001f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].mutate(); 1002f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 100372146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 1004f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1005f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = true; 100672146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 100772146433322588c1116ee06c27ac758ad09d869cAlan Viverette 1008727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette final void clearMutated() { 1009727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette final int N = mNumChildren; 1010727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette final Drawable[] drawables = mDrawables; 1011727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette for (int i = 0; i < N; i++) { 1012727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette if (drawables[i] != null) { 1013727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette drawables[i].clearMutated(); 1014727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1015727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1016727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 1017727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 1018727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1019727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 1020f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 1021f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * A boolean value indicating whether to use the maximum padding value 1022f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * of all frames in the set (false), or to use the padding value of the 1023f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * frame being shown (true). Default value is false. 1024f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 102583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setVariablePadding(boolean variable) { 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = variable; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 102983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Rect getConstantPadding() { 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVariablePadding) { 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1033f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1034f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if ((mConstantPadding != null) || mCheckedPadding) { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantPadding; 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1038f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1039f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 10405140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy Rect r = null; 104183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Rect t = new Rect(); 1042f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 104383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 104483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 104583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy if (drawables[i].getPadding(t)) { 10465140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy if (r == null) r = new Rect(0, 0, 0, 0); 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.left > r.left) r.left = t.left; 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.top > r.top) r.top = t.top; 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.right > r.right) r.right = t.right; 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.bottom > r.bottom) r.bottom = t.bottom; 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1053f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1054f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedPadding = true; 10555140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy return (mConstantPadding = r); 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 105883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setConstantSize(boolean constant) { 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = constant; 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 106283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final boolean isConstantSize() { 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantSize; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 106683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantWidth() { 1067f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantWidth; 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 107483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantHeight() { 1075f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantHeight; 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 108283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumWidth() { 1083f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumWidth; 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumHeight() { 1091f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumHeight; 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne protected void computeConstantSize() { 1099f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedConstantSize = true; 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1101f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1102f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1103f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 110483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 110578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne mConstantWidth = mConstantHeight = -1; 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantMinimumWidth = mConstantMinimumHeight = 0; 110783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 1108f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable dr = drawables[i]; 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int s = dr.getIntrinsicWidth(); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantWidth) mConstantWidth = s; 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getIntrinsicHeight(); 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantHeight) mConstantHeight = s; 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumWidth(); 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumWidth) mConstantMinimumWidth = s; 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumHeight(); 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumHeight) mConstantMinimumHeight = s; 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1120079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setEnterFadeDuration(int duration) { 1121079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = duration; 1122079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1123079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1124079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getEnterFadeDuration() { 1125079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mEnterFadeDuration; 1126079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1127079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1128079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setExitFadeDuration(int duration) { 1129079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = duration; 1130079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1131079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1132079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getExitFadeDuration() { 1133079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mExitFadeDuration; 1134079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1135079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 113683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getOpacity() { 1137f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedOpacity) { 1138f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mOpacity; 1139f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 1140f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1141f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1142f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1143f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 114483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 1145f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; 114683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 1; i < N; i++) { 114783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOpacity = op; 1151eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette mCheckedOpacity = true; 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return op; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 115483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isStateful() { 1156f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedStateful) { 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateful; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1160f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1161f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1162f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 1163f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 1164eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette boolean isStateful = false; 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 1166f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].isStateful()) { 1167eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette isStateful = true; 1168eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette break; 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1171f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1172eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette mStateful = isStateful; 1173eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette mCheckedStateful = true; 1174eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette return isStateful; 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 117783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public void growArray(int oldSize, int newSize) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable[] newDrawables = new Drawable[newSize]; 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize); 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = newDrawables; 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized boolean canConstantState() { 1184f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedConstantState) { 1185f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mCanConstantState; 1186f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 1187f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1188f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1189f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1190f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 1191f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1192f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 1193f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 1194f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 1195f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].getConstantState() == null) { 1196f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = false; 1197f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1201f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 1202f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 1203f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 1204f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1207f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette protected void setConstantState(DrawableContainerState state) { 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawableContainerState = state; 1209ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette 1210ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette // The locally cached drawables may have changed. 1211ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette if (mCurIndex >= 0) { 1212ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mCurrDrawable = state.getChild(mCurIndex); 1213419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette if (mCurrDrawable != null) { 1214419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette initializeDrawableForDisplay(mCurrDrawable); 1215419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 1216ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette } 1217419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 1218419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette // Clear out the last drawable. We don't have enough information to 1219419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette // propagate local state from the past. 1220419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette mLastIndex = -1; 1221419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette mLastDrawable = null; 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12236d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12246d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette /** 12256d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette * Callback that blocks drawable invalidation. 12266d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette */ 12276d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette private static class BlockInvalidateCallback implements Drawable.Callback { 12286d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette private Drawable.Callback mCallback; 12296d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12306d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public BlockInvalidateCallback wrap(Drawable.Callback callback) { 12316d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback = callback; 12326d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette return this; 12336d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12346d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12356d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public Drawable.Callback unwrap() { 12366d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette final Drawable.Callback callback = mCallback; 12376d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback = null; 12386d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette return callback; 12396d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12406d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12416d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette @Override 12426d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public void invalidateDrawable(@NonNull Drawable who) { 12436d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette // Ignore invalidation. 12446d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12456d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12466d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette @Override 12476d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { 12486d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette if (mCallback != null) { 12496d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback.scheduleDrawable(who, what, when); 12506d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12516d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12526d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12536d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette @Override 12546d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { 12556d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette if (mCallback != null) { 12566d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback.unscheduleDrawable(who, what); 12576d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12586d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12596d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1261