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. 213ad7e748543f69794bbc8114da660eed705a89087Alan Viverette * 214079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 215079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 216079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setEnterFadeDuration(int ms) { 217079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mEnterFadeDuration = ms; 218079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 219f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 220079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn /** 221079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * Change the global fade duration when a new drawable is leaving 222079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * the scene. 223ad7e748543f69794bbc8114da660eed705a89087Alan Viverette * 224079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn * @param ms The amount of time to fade in milliseconds. 225079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn */ 226079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void setExitFadeDuration(int ms) { 227079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mDrawableContainerState.mExitFadeDuration = ms; 228079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 229f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 232079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 233079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setBounds(bounds); 234079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setBounds(bounds); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 239f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.isStateful(); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 244f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 245f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He /** @hide */ 246f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He @Override 247f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He public boolean hasFocusStateSpecified() { 248f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He if (mCurrDrawable != null) { 249f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He return mCurrDrawable.hasFocusStateSpecified(); 250f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He } 251f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He if (mLastDrawable != null) { 252f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He return mLastDrawable.hasFocusStateSpecified(); 253f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He } 254f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He return false; 255f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He } 256f380072eeffdb5f993e5bd1c31571afe11d1a82eJiaquan He 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2583f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public void setAutoMirrored(boolean mirrored) { 259729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette if (mDrawableContainerState.mAutoMirrored != mirrored) { 260729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette mDrawableContainerState.mAutoMirrored = mirrored; 261729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette if (mCurrDrawable != null) { 2629b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAutoMirrored(mDrawableContainerState.mAutoMirrored); 263729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette } 2643f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2653f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2663f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 2673f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 2683f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio public boolean isAutoMirrored() { 2693f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio return mDrawableContainerState.mAutoMirrored; 2703f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio } 2713f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 2723f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio @Override 273079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public void jumpToCurrentState() { 274079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean changed = false; 275079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 276079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.jumpToCurrentState(); 277079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 278ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = -1; 279079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 280079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 281079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 282079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.jumpToCurrentState(); 283729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette if (mHasAlpha) { 2849b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(mAlpha); 285729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette } 286079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 287079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 288079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 289079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 290079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 291079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 292079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 293079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn changed = true; 294079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 295079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (changed) { 296079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 297079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 298079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 299079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 300079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override 301c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette public void setHotspot(float x, float y) { 302307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette if (mCurrDrawable != null) { 303c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette mCurrDrawable.setHotspot(x, y); 304307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette } 305307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette } 306307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette 307307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette @Override 30853a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette public void setHotspotBounds(int left, int top, int right, int bottom) { 3097068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette if (mHotspotBounds == null) { 31027cf86939d918b2d6b32a0650a48b8a2afaa26b6Alexander Martinz mHotspotBounds = new Rect(left, top, right, bottom); 3117068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } else { 31227cf86939d918b2d6b32a0650a48b8a2afaa26b6Alexander Martinz mHotspotBounds.set(left, top, right, bottom); 3137068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 3147068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette 31553a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette if (mCurrDrawable != null) { 31653a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette mCurrDrawable.setHotspotBounds(left, top, right, bottom); 31753a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette } 31853a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette } 31953a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette 3207068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette @Override 3217068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette public void getHotspotBounds(Rect outRect) { 3227068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette if (mHotspotBounds != null) { 3237068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette outRect.set(mHotspotBounds); 3247068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } else { 3257068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette super.getHotspotBounds(outRect); 3267068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 3277068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 3287068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette 32953a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette @Override 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onStateChange(int[] state) { 331079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 332079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setState(state); 333079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setState(state); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3410b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette protected boolean onLevelChange(int level) { 342079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 343079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mLastDrawable.setLevel(level); 344079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable.setLevel(level); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 352dfa4646eca54511a28f2c61e1f4b9c697e05a913Alan Viverette public boolean onLayoutDirectionChanged(@View.ResolvedLayoutDir int layoutDirection) { 353a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Let the container handle setting its own layout direction. Otherwise, 354a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // we're accessing potentially unused states. 355a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawableContainerState.setLayoutDirection(layoutDirection, getCurrentIndex()); 356a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 357a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 358a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantWidth(); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantHeight(); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 373f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumWidth() { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumWidth(); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinimumHeight() { 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.isConstantSize()) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState.getConstantMinimumHeight(); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39072146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 391f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void invalidateDrawable(@NonNull Drawable who) { 392ad7e748543f69794bbc8114da660eed705a89087Alan Viverette // This may have been called as the result of a tint changing, in 393ad7e748543f69794bbc8114da660eed705a89087Alan Viverette // which case we may need to refresh the cached statefulness or 394ad7e748543f69794bbc8114da660eed705a89087Alan Viverette // opacity. 395ad7e748543f69794bbc8114da660eed705a89087Alan Viverette if (mDrawableContainerState != null) { 396ad7e748543f69794bbc8114da660eed705a89087Alan Viverette mDrawableContainerState.invalidateCache(); 397ad7e748543f69794bbc8114da660eed705a89087Alan Viverette } 398ad7e748543f69794bbc8114da660eed705a89087Alan Viverette 399f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 400f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().invalidateDrawable(this); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 40472146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 405f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { 406f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 407f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().scheduleDrawable(this, what, when); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41172146433322588c1116ee06c27ac758ad09d869cAlan Viverette @Override 412f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { 413f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (who == mCurrDrawable && getCallback() != null) { 414f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy getCallback().unscheduleDrawable(this, what); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setVisible(boolean visible, boolean restart) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed = super.setVisible(visible, restart); 421079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 422079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(visible, restart); 423079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable.setVisible(visible, restart); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return changed; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 43283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT : 43383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy mDrawableContainerState.getOpacity(); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4365e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette /** @hide */ 4375e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette public void setCurrentIndex(int index) { 4385e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette selectDrawable(index); 4395e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette } 4405e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette 4415e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette /** @hide */ 4425e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette public int getCurrentIndex() { 4435e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette return mCurIndex; 4445e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette } 4455e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette 446a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette /** 447a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * Sets the currently displayed drawable by index. 448a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * <p> 449a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * If an invalid index is specified, the current drawable will be set to 450a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * {@code null} and the index will be set to {@code -1}. 451a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * 452a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * @param index the index of the drawable to display 453a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette * @return {@code true} if the drawable changed, {@code false} otherwise 454a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette */ 455a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette public boolean selectDrawable(int index) { 456a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette if (index == mCurIndex) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 459079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 460079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 461079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 462a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + index 463079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + ": exit=" + mDrawableContainerState.mExitFadeDuration 464079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn + " enter=" + mDrawableContainerState.mEnterFadeDuration); 465079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 466079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mExitFadeDuration > 0) { 467079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 468079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 469079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrDrawable != null) { 471079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = mCurrDrawable; 472ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = mCurIndex; 473079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration; 474079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 475079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 476ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = -1; 477079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 479079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else if (mCurrDrawable != null) { 480079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mCurrDrawable.setVisible(false, false); 481079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 482079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 483a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette if (index >= 0 && index < mDrawableContainerState.mNumChildren) { 484a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette final Drawable d = mDrawableContainerState.getChild(index); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = d; 486a02d2748be353393b7b593d5adbd37d80dee427dAlan Viverette mCurIndex = index; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d != null) { 488079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mDrawableContainerState.mEnterFadeDuration > 0) { 489079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration; 4907068c39526459c18a020e29c1ebfa6aed54e2d0fAlan Viverette } 491419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette initializeDrawableForDisplay(d); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrDrawable = null; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIndex = -1; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 497079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 498079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) { 499079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mAnimationRunnable == null) { 500079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mAnimationRunnable = new Runnable() { 501079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn @Override public void run() { 502079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 503079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn invalidateSelf(); 504079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 505079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn }; 506079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 507079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn unscheduleSelf(mAnimationRunnable); 508079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 509079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn // Compute first frame and schedule next animation. 510079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animate(true); 511079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 512079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 514079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 517f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 518419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette /** 519419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette * Initializes a drawable for display in this container. 520419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette * 521419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette * @param d The drawable to initialize. 522419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette */ 523419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette private void initializeDrawableForDisplay(Drawable d) { 5246d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette if (mBlockInvalidateCallback == null) { 5256d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mBlockInvalidateCallback = new BlockInvalidateCallback(); 5266d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 5276d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 5282b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // Temporary fix for suspending callbacks during initialization. We 5292b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // don't want any of these setters causing an invalidate() since that 5302b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // may call back into DrawableContainer. 5316d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette d.setCallback(mBlockInvalidateCallback.wrap(d.getCallback())); 5322b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette 5332b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette try { 5342b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mEnterFadeDuration <= 0 && mHasAlpha) { 5352b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setAlpha(mAlpha); 536419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 537419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 5382b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mHasColorFilter) { 5392b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette // Color filter always overrides tint. 5402b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setColorFilter(mDrawableContainerState.mColorFilter); 5412b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } else { 5422b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mHasTintList) { 5432b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setTintList(mDrawableContainerState.mTintList); 5442b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 5452b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (mDrawableContainerState.mHasTintMode) { 5462b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setTintMode(mDrawableContainerState.mTintMode); 5472b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 5482b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 549419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 5502b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setVisible(isVisible(), true); 5512b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setDither(mDrawableContainerState.mDither); 5522b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setState(getState()); 5532b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setLevel(getLevel()); 5542b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setBounds(getBounds()); 5552b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setLayoutDirection(getLayoutDirection()); 5562b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setAutoMirrored(mDrawableContainerState.mAutoMirrored); 5572b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette 5582b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette final Rect hotspotBounds = mHotspotBounds; 5592b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette if (hotspotBounds != null) { 5602b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette d.setHotspotBounds(hotspotBounds.left, hotspotBounds.top, 5612b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette hotspotBounds.right, hotspotBounds.bottom); 5622b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } 5632b561f1c352df95df23e17e7fce2acc3144df159Alan Viverette } finally { 5646d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette d.setCallback(mBlockInvalidateCallback.unwrap()); 565419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 566419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 567419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 568079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn void animate(boolean schedule) { 569729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette mHasAlpha = true; 570729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette 571079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn final long now = SystemClock.uptimeMillis(); 572079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn boolean animating = false; 573079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mCurrDrawable != null) { 574079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd != 0) { 575079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mEnterAnimationEnd <= now) { 5769b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(mAlpha); 577079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 578079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 579079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mEnterAnimationEnd-now)*255) 580079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mEnterFadeDuration; 5819b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mCurrDrawable.setAlpha(((255-animAlpha)*mAlpha)/255); 582079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 583079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 584079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 585079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 586079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterAnimationEnd = 0; 587079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 588079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mLastDrawable != null) { 589079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd != 0) { 590079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (mExitAnimationEnd <= now) { 591079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable.setVisible(false, false); 592079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mLastDrawable = null; 593ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mLastIndex = -1; 594079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 595079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 596079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn int animAlpha = (int)((mExitAnimationEnd-now)*255) 597079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn / mDrawableContainerState.mExitFadeDuration; 5989b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette mLastDrawable.setAlpha((animAlpha*mAlpha)/255); 599079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn animating = true; 600079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 601079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 602079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } else { 603079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitAnimationEnd = 0; 604079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 605079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 606079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (schedule && animating) { 6078dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette scheduleSelf(mAnimationRunnable, now + 1000 / 60); 608079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 609079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 610079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getCurrent() { 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCurrDrawable; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 616f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette /** 617f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * Updates the source density based on the resources used to inflate 618f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * density-dependent values. Implementing classes should call this method 619f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * during inflation. 620f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * 621f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * @param res the resources used to inflate density-dependent values 6220c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu * @hide 623f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette */ 6240c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu protected final void updateDensity(Resources res) { 625f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mDrawableContainerState.updateDensity(res); 626f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 627f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 62952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void applyTheme(Theme theme) { 63052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mDrawableContainerState.applyTheme(theme); 63152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 63252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 63352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 63452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 63552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return mDrawableContainerState.canApplyTheme(); 63652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 63752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 63852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDrawableContainerState.canConstantState()) { 6416efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mDrawableContainerState.mChangingConfigurations = getChangingConfigurations(); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawableContainerState; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 6505ed8f27858dbdf85203068eca46eef0a65f3344eAlan Viverette final DrawableContainerState clone = cloneConstantState(); 6515ed8f27858dbdf85203068eca46eef0a65f3344eAlan Viverette clone.mutate(); 6525ed8f27858dbdf85203068eca46eef0a65f3344eAlan Viverette setConstantState(clone); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 65878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne /** 6598dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * Returns a shallow copy of the container's constant state to be used as 6608dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * the base state for {@link #mutate()}. 6618dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * 6628dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette * @return a shallow copy of the constant state 6638dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette */ 6648dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette DrawableContainerState cloneConstantState() { 6658dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette return mDrawableContainerState; 6668dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette } 6678dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette 6688dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette /** 669727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 670727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 671727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 672727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 673727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mDrawableContainerState.clearMutated(); 674727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 675727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 676727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 677727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 67878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A ConstantState that can contain several {@link Drawable}s. 67978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * 68078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * This class was made public to enable testing, and its visibility may change in a future 68178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * release. 68278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */ 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract static class DrawableContainerState extends ConstantState { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DrawableContainer mOwner; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 686f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette Resources mSourceRes; 687f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette int mDensity = DisplayMetrics.DENSITY_DEFAULT; 688ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette @Config int mChangingConfigurations; 689ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette @Config int mChildrenChangingConfigurations; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6911259f616c26f89dd5000745d7c364fae41b23682Alan Viverette SparseArray<ConstantState> mDrawableFutures; 692f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Drawable[] mDrawables; 693f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mNumChildren; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 695d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette boolean mVariablePadding = false; 696f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette boolean mCheckedPadding; 697f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette Rect mConstantPadding; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette boolean mConstantSize = false; 700f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette boolean mCheckedConstantSize; 701f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantWidth; 702f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantHeight; 703f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumWidth; 704f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mConstantMinimumHeight; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 706f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedOpacity; 707f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mOpacity; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedStateful; 710f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mStateful; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 712f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCheckedConstantState; 713f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mCanConstantState; 7145140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy 715f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mDither = DEFAULT_DITHER; 716f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 717f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette boolean mMutated; 718f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int mLayoutDirection; 719f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 720d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette int mEnterFadeDuration = 0; 721d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette int mExitFadeDuration = 0; 722079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 7233f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio boolean mAutoMirrored; 7243f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio 725d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette ColorFilter mColorFilter; 726729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette boolean mHasColorFilter; 727d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette 728bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette ColorStateList mTintList; 729b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette Mode mTintMode; 730bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette boolean mHasTintList; 731bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette boolean mHasTintMode; 732b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 7330c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu /** 7340c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu * @hide 7350c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu */ 7360c03664fa6acbe5c3fd11d54ab9a6792f43dda07Teng-Hui Zhu protected DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, 737c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn Resources res) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOwner = owner; 739ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mSourceRes = res != null ? res : (orig != null ? orig.mSourceRes : null); 740ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDensity = Drawable.resolveDensity(res, orig != null ? orig.mDensity : 0); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (orig != null) { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = orig.mChangingConfigurations; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 746f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 747f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = orig.mVariablePadding; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = orig.mConstantSize; 751a41581ed4033004c73115113f45b9844e9b0210fRomain Guy mDither = orig.mDither; 752f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = orig.mMutated; 753f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = orig.mLayoutDirection; 754079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = orig.mEnterFadeDuration; 755079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = orig.mExitFadeDuration; 7563f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio mAutoMirrored = orig.mAutoMirrored; 757d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette mColorFilter = orig.mColorFilter; 758729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette mHasColorFilter = orig.mHasColorFilter; 759bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mTintList = orig.mTintList; 760b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = orig.mTintMode; 761bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mHasTintList = orig.mHasTintList; 762bddb843e793a279db99888dd78b4f74a362cbb8bAlan Viverette mHasTintMode = orig.mHasTintMode; 763079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 764ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mDensity == mDensity) { 765f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedPadding) { 766f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantPadding = new Rect(orig.mConstantPadding); 767f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedPadding = true; 768f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 769f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 770f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedConstantSize) { 771f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantWidth = orig.mConstantWidth; 772f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantHeight = orig.mConstantHeight; 773f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantMinimumWidth = orig.mConstantMinimumWidth; 774f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mConstantMinimumHeight = orig.mConstantMinimumHeight; 775f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedConstantSize = true; 776f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 777f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 778f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 779f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedOpacity) { 780f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mOpacity = orig.mOpacity; 781f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedOpacity = true; 782f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 783f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 784f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (orig.mCheckedStateful) { 785f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mStateful = orig.mStateful; 786f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedStateful = true; 787f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 788f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 789f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Postpone cloning children and futures until we're absolutely 790f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // sure that we're done computing values for the original state. 791f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] origDr = orig.mDrawables; 792f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables = new Drawable[origDr.length]; 793f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mNumChildren = orig.mNumChildren; 794f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 7951259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final SparseArray<ConstantState> origDf = orig.mDrawableFutures; 796f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDf != null) { 797f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = origDf.clone(); 798f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } else { 79906ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette mDrawableFutures = new SparseArray<>(mNumChildren); 800f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 801f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 80262b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette // Create futures for drawables with constant states. If a 80362b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette // drawable doesn't have a constant state, then we can't clone 80462b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette // it and we'll have to reference the original. 805f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 806f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 807f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (origDr[i] != null) { 8081259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState cs = origDr[i].getConstantState(); 8091259f616c26f89dd5000745d7c364fae41b23682Alan Viverette if (cs != null) { 8101259f616c26f89dd5000745d7c364fae41b23682Alan Viverette mDrawableFutures.put(i, cs); 81162b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette } else { 81262b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette mDrawables[i] = origDr[i]; 81362b780e85ff2fcefd4324c3bfbf49b14963cf58bAlan Viverette } 814f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 815f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = new Drawable[10]; 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren = 0; 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 821f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 823ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 824dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio return mChangingConfigurations | mChildrenChangingConfigurations; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 827a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette /** 828a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * Adds the drawable to the end of the list of contained drawables. 829a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * 830a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * @param dr the drawable to add 831a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette * @return the position of the drawable within the container 832a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette */ 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int addChild(Drawable dr) { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int pos = mNumChildren; 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos >= mDrawables.length) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project growArray(pos, pos+10); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839a24c9b4791dddc2dbc233dfe8dac1ae682beb272Alan Viverette dr.mutate(); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setVisible(false, true); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dr.setCallback(mOwner); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables[pos] = dr; 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumChildren++; 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildrenChangingConfigurations |= dr.getChangingConfigurations(); 846ad7e748543f69794bbc8114da660eed705a89087Alan Viverette 847ad7e748543f69794bbc8114da660eed705a89087Alan Viverette invalidateCache(); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantPadding = null; 850f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedPadding = false; 851f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedConstantSize = false; 8525291a9571580d5147331adbdefb017fa395df505Alan Viverette mCheckedConstantState = false; 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pos; 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 857ad7e748543f69794bbc8114da660eed705a89087Alan Viverette /** 858ad7e748543f69794bbc8114da660eed705a89087Alan Viverette * Invalidates the cached opacity and statefulness. 859ad7e748543f69794bbc8114da660eed705a89087Alan Viverette */ 860ad7e748543f69794bbc8114da660eed705a89087Alan Viverette void invalidateCache() { 861ad7e748543f69794bbc8114da660eed705a89087Alan Viverette mCheckedOpacity = false; 862ad7e748543f69794bbc8114da660eed705a89087Alan Viverette mCheckedStateful = false; 863ad7e748543f69794bbc8114da660eed705a89087Alan Viverette } 864ad7e748543f69794bbc8114da660eed705a89087Alan Viverette 86572146433322588c1116ee06c27ac758ad09d869cAlan Viverette final int getCapacity() { 86672146433322588c1116ee06c27ac758ad09d869cAlan Viverette return mDrawables.length; 86772146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 86872146433322588c1116ee06c27ac758ad09d869cAlan Viverette 8691259f616c26f89dd5000745d7c364fae41b23682Alan Viverette private void createAllFutures() { 870f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 871f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int futureCount = mDrawableFutures.size(); 872f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { 873f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int index = mDrawableFutures.keyAt(keyIndex); 8741259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState cs = mDrawableFutures.valueAt(keyIndex); 8751259f616c26f89dd5000745d7c364fae41b23682Alan Viverette mDrawables[index] = prepareDrawable(cs.newDrawable(mSourceRes)); 876f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 877f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 878f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures = null; 879f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 880f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 881f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 8821259f616c26f89dd5000745d7c364fae41b23682Alan Viverette private Drawable prepareDrawable(Drawable child) { 8831259f616c26f89dd5000745d7c364fae41b23682Alan Viverette child.setLayoutDirection(mLayoutDirection); 8849b4bdeff6dea5a24a3085a17d2dde9003642af79Alan Viverette child = child.mutate(); 885b46ba3b2b0268688852cdf3d1fb4afe4873d63beAlan Viverette child.setCallback(mOwner); 8861259f616c26f89dd5000745d7c364fae41b23682Alan Viverette return child; 8871259f616c26f89dd5000745d7c364fae41b23682Alan Viverette } 8881259f616c26f89dd5000745d7c364fae41b23682Alan Viverette 88983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getChildCount() { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNumChildren; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89372146433322588c1116ee06c27ac758ad09d869cAlan Viverette /* 89472146433322588c1116ee06c27ac758ad09d869cAlan Viverette * @deprecated Use {@link #getChild} instead. 89572146433322588c1116ee06c27ac758ad09d869cAlan Viverette */ 89683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Drawable[] getChildren() { 897f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Create all futures for backwards compatibility. 898f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 899f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDrawables; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 90372146433322588c1116ee06c27ac758ad09d869cAlan Viverette public final Drawable getChild(int index) { 904f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable result = mDrawables[index]; 905f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (result != null) { 906f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return result; 907f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 908f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 909f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // Prepare future drawable if necessary. 910f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mDrawableFutures != null) { 911f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int keyIndex = mDrawableFutures.indexOfKey(index); 912f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (keyIndex >= 0) { 9131259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState cs = mDrawableFutures.valueAt(keyIndex); 9141259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final Drawable prepared = prepareDrawable(cs.newDrawable(mSourceRes)); 915f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawables[index] = prepared; 916f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mDrawableFutures.removeAt(keyIndex); 91706ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette if (mDrawableFutures.size() == 0) { 91806ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette mDrawableFutures = null; 91906ff2af68aa1041eeb26778e994e0fe196bf8b1eAlan Viverette } 920f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return prepared; 921f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 922f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 923f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 924f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return null; 925f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 926f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 927a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean setLayoutDirection(int layoutDirection, int currentIndex) { 928a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette boolean changed = false; 929a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 930f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 931f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // change layout direction when they are prepared. 932f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 933f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 934f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 935f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 936a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean childChanged = drawables[i].setLayoutDirection(layoutDirection); 937a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (i == currentIndex) { 938a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette changed = childChanged; 939a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 940f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 941f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 942f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 943f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mLayoutDirection = layoutDirection; 944a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 945a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return changed; 94672146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 94772146433322588c1116ee06c27ac758ad09d869cAlan Viverette 948f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette /** 949f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * Updates the source density based on the resources used to inflate 950f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * density-dependent values. 951f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * 952f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette * @param res the resources used to inflate density-dependent values 953f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette */ 954f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette final void updateDensity(Resources res) { 9552d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette if (res != null) { 956f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mSourceRes = res; 957f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 9582d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette // The density may have changed since the last update (if any). Any 9592d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette // dimension-type attributes will need their default values scaled. 9602d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette final int targetDensity = Drawable.resolveDensity(res, mDensity); 9612d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette final int sourceDensity = mDensity; 9622d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette mDensity = targetDensity; 963f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 9642d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette if (sourceDensity != targetDensity) { 9652d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette mCheckedConstantSize = false; 9662d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette mCheckedPadding = false; 9672d3ca47ef83c097e3a1aaa66f2d119be0e93e677Alan Viverette } 968f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 969f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette } 970f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 97152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final void applyTheme(Theme theme) { 97217cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (theme != null) { 97317cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette createAllFutures(); 97417cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette 97517cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final int N = mNumChildren; 97617cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final Drawable[] drawables = mDrawables; 97717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette for (int i = 0; i < N; i++) { 97817cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (drawables[i] != null && drawables[i].canApplyTheme()) { 97917cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette drawables[i].applyTheme(theme); 980e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 981e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette // Update cached mask of child changing configurations. 982e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mChildrenChangingConfigurations |= drawables[i].getChangingConfigurations(); 98317cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette } 98452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 985f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette 986f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette updateDensity(theme.getResources()); 98752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 98852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 98952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 99052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 99152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 99252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int N = mNumChildren; 99352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final Drawable[] drawables = mDrawables; 99452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette for (int i = 0; i < N; i++) { 995b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final Drawable d = drawables[i]; 99652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (d != null) { 99752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (d.canApplyTheme()) { 99852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return true; 99952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 100052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 10011259f616c26f89dd5000745d7c364fae41b23682Alan Viverette final ConstantState future = mDrawableFutures.get(i); 100252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (future != null && future.canApplyTheme()) { 100352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return true; 100452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 100552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 100652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 100752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 100852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return false; 100952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 101052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 10118dcd533786df8d824f1e040230ee9e7e5b083998Alan Viverette private void mutate() { 1012f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // No need to call createAllFutures, since future drawables will 1013f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette // mutate when they are prepared. 1014f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 101572146433322588c1116ee06c27ac758ad09d869cAlan Viverette final Drawable[] drawables = mDrawables; 101672146433322588c1116ee06c27ac758ad09d869cAlan Viverette for (int i = 0; i < N; i++) { 1017f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i] != null) { 1018f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette drawables[i].mutate(); 1019f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 102072146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 1021f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1022f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mMutated = true; 102372146433322588c1116ee06c27ac758ad09d869cAlan Viverette } 102472146433322588c1116ee06c27ac758ad09d869cAlan Viverette 1025727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette final void clearMutated() { 1026727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette final int N = mNumChildren; 1027727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette final Drawable[] drawables = mDrawables; 1028727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette for (int i = 0; i < N; i++) { 1029727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette if (drawables[i] != null) { 1030727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette drawables[i].clearMutated(); 1031727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1032727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1033727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 1034727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 1035727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1036727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 1037f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette /** 1038f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * A boolean value indicating whether to use the maximum padding value 1039f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * of all frames in the set (false), or to use the padding value of the 1040f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette * frame being shown (true). Default value is false. 1041f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette */ 104283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setVariablePadding(boolean variable) { 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVariablePadding = variable; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 104683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final Rect getConstantPadding() { 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVariablePadding) { 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1050f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1051f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if ((mConstantPadding != null) || mCheckedPadding) { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantPadding; 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1055f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1056f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 10575140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy Rect r = null; 105883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Rect t = new Rect(); 1059f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 106083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 106183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 106283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy if (drawables[i].getPadding(t)) { 10635140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy if (r == null) r = new Rect(0, 0, 0, 0); 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.left > r.left) r.left = t.left; 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.top > r.top) r.top = t.top; 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.right > r.right) r.right = t.right; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.bottom > r.bottom) r.bottom = t.bottom; 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1070f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1071f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedPadding = true; 10725140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy return (mConstantPadding = r); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 107583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final void setConstantSize(boolean constant) { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantSize = constant; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 107983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final boolean isConstantSize() { 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantSize; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 108383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantWidth() { 1084f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantWidth; 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantHeight() { 1092f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantHeight; 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumWidth() { 1100f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumWidth; 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 110783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getConstantMinimumHeight() { 1108f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette if (!mCheckedConstantSize) { 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project computeConstantSize(); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mConstantMinimumHeight; 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 111578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne protected void computeConstantSize() { 1116f1f5f6fcaa768c5b88e9a56f18cbd6ecf72755a8Alan Viverette mCheckedConstantSize = true; 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1118f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1119f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1120f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 112183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 112278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne mConstantWidth = mConstantHeight = -1; 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstantMinimumWidth = mConstantMinimumHeight = 0; 112483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 0; i < N; i++) { 1125f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable dr = drawables[i]; 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int s = dr.getIntrinsicWidth(); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantWidth) mConstantWidth = s; 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getIntrinsicHeight(); 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantHeight) mConstantHeight = s; 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumWidth(); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumWidth) mConstantMinimumWidth = s; 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = dr.getMinimumHeight(); 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s > mConstantMinimumHeight) mConstantMinimumHeight = s; 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1137079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setEnterFadeDuration(int duration) { 1138079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mEnterFadeDuration = duration; 1139079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1140079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1141079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getEnterFadeDuration() { 1142079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mEnterFadeDuration; 1143079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1144079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1145079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final void setExitFadeDuration(int duration) { 1146079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mExitFadeDuration = duration; 1147079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1148079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1149079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn public final int getExitFadeDuration() { 1150079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn return mExitFadeDuration; 1151079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 1152079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 115383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public final int getOpacity() { 1154f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedOpacity) { 1155f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mOpacity; 1156f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 1157f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1158f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1159f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1160f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 116183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy final Drawable[] drawables = mDrawables; 1162f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; 116383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy for (int i = 1; i < N; i++) { 116483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1166f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOpacity = op; 1168eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette mCheckedOpacity = true; 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return op; 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 117183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final boolean isStateful() { 1173f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedStateful) { 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateful; 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1176f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1177f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1178f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1179f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 1180f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 1181eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette boolean isStateful = false; 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 1183f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].isStateful()) { 1184eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette isStateful = true; 1185eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette break; 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1188f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1189eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette mStateful = isStateful; 1190eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette mCheckedStateful = true; 1191eb7277590a2c2bdd64534da4c822a69440df32dfAlan Viverette return isStateful; 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 119483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy public void growArray(int oldSize, int newSize) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable[] newDrawables = new Drawable[newSize]; 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawables = newDrawables; 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized boolean canConstantState() { 1201f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (mCheckedConstantState) { 1202f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return mCanConstantState; 1203f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 1204f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1205f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette createAllFutures(); 1206f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1207f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCheckedConstantState = true; 1208f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 1209f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final int N = mNumChildren; 1210f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette final Drawable[] drawables = mDrawables; 1211f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette for (int i = 0; i < N; i++) { 1212f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette if (drawables[i].getConstantState() == null) { 1213f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = false; 1214f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return false; 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1218f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette mCanConstantState = true; 1219f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette return true; 1220f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette } 1221f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1224f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette protected void setConstantState(DrawableContainerState state) { 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawableContainerState = state; 1226ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette 1227ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette // The locally cached drawables may have changed. 1228ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette if (mCurIndex >= 0) { 1229ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette mCurrDrawable = state.getChild(mCurIndex); 1230419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette if (mCurrDrawable != null) { 1231419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette initializeDrawableForDisplay(mCurrDrawable); 1232419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 1233ebc9f2e773c3ebb4d4af3025fc6770844cc8fdefAlan Viverette } 1234419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 1235419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette // Clear out the last drawable. We don't have enough information to 1236419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette // propagate local state from the past. 1237419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette mLastIndex = -1; 1238419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette mLastDrawable = null; 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12406d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12416d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette /** 12426d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette * Callback that blocks drawable invalidation. 12436d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette */ 12446d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette private static class BlockInvalidateCallback implements Drawable.Callback { 12456d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette private Drawable.Callback mCallback; 12466d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12476d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public BlockInvalidateCallback wrap(Drawable.Callback callback) { 12486d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback = callback; 12496d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette return this; 12506d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12516d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12526d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public Drawable.Callback unwrap() { 12536d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette final Drawable.Callback callback = mCallback; 12546d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback = null; 12556d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette return callback; 12566d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12576d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12586d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette @Override 12596d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public void invalidateDrawable(@NonNull Drawable who) { 12606d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette // Ignore invalidation. 12616d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12626d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12636d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette @Override 12646d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { 12656d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette if (mCallback != null) { 12666d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback.scheduleDrawable(who, what, when); 12676d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12686d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12696d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette 12706d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette @Override 12716d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { 12726d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette if (mCallback != null) { 12736d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette mCallback.unscheduleDrawable(who, what); 12746d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12756d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12766d823891bbfc043f2a8ba6b5d6e6baa84cf750f6Alan Viverette } 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1278