Loading graphics/java/android/graphics/drawable/DrawableContainer.java +224 −101 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.SystemClock; import android.util.SparseArray; /** * A helper class that contains several {@link Drawable}s and selects which one to use. Loading Loading @@ -316,7 +317,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) { Drawable d = mDrawableContainerState.mDrawables[idx]; final Drawable d = mDrawableContainerState.getChild(idx); mCurrDrawable = d; mCurIndex = idx; if (d != null) { Loading Loading @@ -432,6 +433,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { */ public abstract static class DrawableContainerState extends ConstantState { final DrawableContainer mOwner; final Resources mRes; SparseArray<ConstantStateFuture> mDrawableFutures; int mChangingConfigurations; int mChildrenChangingConfigurations; Loading @@ -439,80 +443,92 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { Drawable[] mDrawables; int mNumChildren; boolean mVariablePadding = false; Rect mConstantPadding = null; boolean mVariablePadding; boolean mPaddingChecked; Rect mConstantPadding; boolean mConstantSize = false; boolean mComputedConstantSize = false; boolean mConstantSize; boolean mComputedConstantSize; int mConstantWidth; int mConstantHeight; int mConstantMinimumWidth; int mConstantMinimumHeight; boolean mCheckedOpacity; int mOpacity; boolean mHaveStateful = false; boolean mCheckedStateful; boolean mStateful; boolean mCheckedConstantState; boolean mCanConstantState; boolean mPaddingChecked = false; boolean mDither = DEFAULT_DITHER; boolean mMutated; int mLayoutDirection; int mEnterFadeDuration; int mExitFadeDuration; DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, Resources res) { mOwner = owner; mRes = res; if (orig != null) { mChangingConfigurations = orig.mChangingConfigurations; mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; final Drawable[] origDr = orig.mDrawables; mCheckedConstantState = true; mCanConstantState = true; mVariablePadding = orig.mVariablePadding; mConstantSize = orig.mConstantSize; mDither = orig.mDither; mMutated = orig.mMutated; mLayoutDirection = orig.mLayoutDirection; mEnterFadeDuration = orig.mEnterFadeDuration; mExitFadeDuration = orig.mExitFadeDuration; // Cloning the following values may require creating futures. mConstantPadding = orig.getConstantPadding(); mPaddingChecked = true; mConstantWidth = orig.getConstantWidth(); mConstantHeight = orig.getConstantHeight(); mConstantMinimumWidth = orig.getConstantMinimumWidth(); mConstantMinimumHeight = orig.getConstantMinimumHeight(); mComputedConstantSize = true; mOpacity = orig.getOpacity(); mCheckedOpacity = true; mStateful = orig.isStateful(); mCheckedStateful = true; // Postpone cloning children and futures until we're absolutely // sure that we're done computing values for the original state. final Drawable[] origDr = orig.mDrawables; mDrawables = new Drawable[origDr.length]; mNumChildren = orig.mNumChildren; final int N = mNumChildren; for (int i=0; i<N; i++) { if (res != null) { mDrawables[i] = origDr[i].getConstantState().newDrawable(res); final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures; if (origDf != null) { mDrawableFutures = origDf.clone(); } else { mDrawables[i] = origDr[i].getConstantState().newDrawable(); } mDrawables[i].setCallback(owner); mDrawables[i].setLayoutDirection(origDr[i].getLayoutDirection()); mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren); } mCheckedConstantState = mCanConstantState = true; mVariablePadding = orig.mVariablePadding; if (orig.mConstantPadding != null) { mConstantPadding = new Rect(orig.mConstantPadding); final int N = mNumChildren; for (int i = 0; i < N; i++) { if (origDr[i] != null) { mDrawableFutures.put(i, new ConstantStateFuture(origDr[i])); } } mConstantSize = orig.mConstantSize; mComputedConstantSize = orig.mComputedConstantSize; mConstantWidth = orig.mConstantWidth; mConstantHeight = orig.mConstantHeight; mConstantMinimumWidth = orig.mConstantMinimumWidth; mConstantMinimumHeight = orig.mConstantMinimumHeight; mOpacity = orig.mOpacity; mHaveStateful = orig.mHaveStateful; mStateful = orig.mStateful; mDither = orig.mDither; mEnterFadeDuration = orig.mEnterFadeDuration; mExitFadeDuration = orig.mExitFadeDuration; } else { mDrawables = new Drawable[10]; mNumChildren = 0; mCheckedConstantState = mCanConstantState = false; } } Loading @@ -534,7 +550,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mDrawables[pos] = dr; mNumChildren++; mChildrenChangingConfigurations |= dr.getChangingConfigurations(); mHaveStateful = false; mCheckedStateful = false; mCheckedOpacity = false; mConstantPadding = null; mPaddingChecked = false; Loading @@ -547,6 +564,18 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return mDrawables.length; } private final void createAllFutures() { if (mDrawableFutures != null) { final int futureCount = mDrawableFutures.size(); for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { final int index = mDrawableFutures.keyAt(keyIndex); mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this); } mDrawableFutures = null; } } public final int getChildCount() { return mNumChildren; } Loading @@ -555,24 +584,64 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { * @deprecated Use {@link #getChild} instead. */ public final Drawable[] getChildren() { // Create all futures for backwards compatibility. createAllFutures(); return mDrawables; } public final Drawable getChild(int index) { return mDrawables[index]; final Drawable result = mDrawables[index]; if (result != null) { return result; } // Prepare future drawable if necessary. if (mDrawableFutures != null) { final int keyIndex = mDrawableFutures.indexOfKey(index); if (keyIndex >= 0) { final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this); mDrawables[index] = prepared; mDrawableFutures.removeAt(keyIndex); return prepared; } } return null; } final void setLayoutDirection(int layoutDirection) { // No need to call createAllFutures, since future drawables will // change layout direction when they are prepared. final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (drawables[i] != null) { drawables[i].setLayoutDirection(layoutDirection); } } mLayoutDirection = layoutDirection; } final void mutate() { final int N = getChildCount(); // No need to call createAllFutures, since future drawables will // mutate when they are prepared. final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (drawables[i] != null) drawables[i].mutate(); if (drawables[i] != null) { drawables[i].mutate(); } } /** A boolean value indicating whether to use the maximum padding value of * all frames in the set (false), or to use the padding value of the frame * being shown (true). Default value is false. mMutated = true; } /** * A boolean value indicating whether to use the maximum padding value * of all frames in the set (false), or to use the padding value of the * frame being shown (true). Default value is false. */ public final void setVariablePadding(boolean variable) { mVariablePadding = variable; Loading @@ -582,13 +651,16 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { if (mVariablePadding) { return null; } if (mConstantPadding != null || mPaddingChecked) { if ((mConstantPadding != null) || mPaddingChecked) { return mConstantPadding; } createAllFutures(); Rect r = null; final Rect t = new Rect(); final int N = getChildCount(); final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (drawables[i].getPadding(t)) { Loading @@ -599,6 +671,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { if (t.bottom > r.bottom) r.bottom = t.bottom; } } mPaddingChecked = true; return (mConstantPadding = r); } Loading Loading @@ -646,12 +719,14 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { protected void computeConstantSize() { mComputedConstantSize = true; final int N = getChildCount(); createAllFutures(); final int N = mNumChildren; final Drawable[] drawables = mDrawables; mConstantWidth = mConstantHeight = -1; mConstantMinimumWidth = mConstantMinimumHeight = 0; for (int i = 0; i < N; i++) { Drawable dr = drawables[i]; final Drawable dr = drawables[i]; int s = dr.getIntrinsicWidth(); if (s > mConstantWidth) mConstantWidth = s; s = dr.getIntrinsicHeight(); Loading Loading @@ -680,33 +755,45 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } public final int getOpacity() { final int N = getChildCount(); if (mCheckedOpacity) { return mOpacity; } createAllFutures(); mCheckedOpacity = true; final int N = mNumChildren; final Drawable[] drawables = mDrawables; int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; for (int i = 1; i < N; i++) { op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); } mOpacity = op; return op; } public final boolean isStateful() { if (mHaveStateful) { if (mCheckedStateful) { return mStateful; } boolean stateful = false; final int N = getChildCount(); createAllFutures(); mCheckedStateful = true; final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (mDrawables[i].isStateful()) { stateful = true; break; if (drawables[i].isStateful()) { mStateful = true; return true; } } mStateful = stateful; mHaveStateful = true; return stateful; mStateful = false; return false; } public void growArray(int oldSize, int newSize) { Loading @@ -716,24 +803,60 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } public synchronized boolean canConstantState() { if (!mCheckedConstantState) { mCanConstantState = true; if (mCheckedConstantState) { return mCanConstantState; } createAllFutures(); mCheckedConstantState = true; final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (mDrawables[i].getConstantState() == null) { if (drawables[i].getConstantState() == null) { mCanConstantState = false; break; return false; } } mCheckedConstantState = true; mCanConstantState = true; return true; } return mCanConstantState; /** * Class capable of cloning a Drawable from another Drawable's * ConstantState. */ private static class ConstantStateFuture { private final ConstantState mConstantState; private ConstantStateFuture(Drawable source) { mConstantState = source.getConstantState(); } /** * Obtains and prepares the Drawable represented by this future. * * @param state the container into which this future will be placed * @return a prepared Drawable */ public Drawable get(DrawableContainerState state) { final Drawable result = (state.mRes == null) ? mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes); result.setLayoutDirection(state.mLayoutDirection); result.setCallback(state.mOwner); if (state.mMutated) { result.mutate(); } return result; } } } protected void setConstantState(DrawableContainerState state) { protected void setConstantState(DrawableContainerState state) { mDrawableContainerState = state; } } graphics/java/android/graphics/drawable/StateListDrawable.java +4 −4 Original line number Diff line number Diff line Loading @@ -264,11 +264,11 @@ public class StateListDrawable extends DrawableContainer { /** @hide */ @Override public void setLayoutDirection(int layoutDirection) { final int numStates = getStateCount(); for (int i = 0; i < numStates; i++) { getStateDrawable(i).setLayoutDirection(layoutDirection); } super.setLayoutDirection(layoutDirection); // Let the container handle setting its own layout direction. Otherwise, // we're accessing potentially unused states. mStateListState.setLayoutDirection(layoutDirection); } static final class StateListState extends DrawableContainerState { Loading Loading
graphics/java/android/graphics/drawable/DrawableContainer.java +224 −101 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.SystemClock; import android.util.SparseArray; /** * A helper class that contains several {@link Drawable}s and selects which one to use. Loading Loading @@ -316,7 +317,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) { Drawable d = mDrawableContainerState.mDrawables[idx]; final Drawable d = mDrawableContainerState.getChild(idx); mCurrDrawable = d; mCurIndex = idx; if (d != null) { Loading Loading @@ -432,6 +433,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { */ public abstract static class DrawableContainerState extends ConstantState { final DrawableContainer mOwner; final Resources mRes; SparseArray<ConstantStateFuture> mDrawableFutures; int mChangingConfigurations; int mChildrenChangingConfigurations; Loading @@ -439,80 +443,92 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { Drawable[] mDrawables; int mNumChildren; boolean mVariablePadding = false; Rect mConstantPadding = null; boolean mVariablePadding; boolean mPaddingChecked; Rect mConstantPadding; boolean mConstantSize = false; boolean mComputedConstantSize = false; boolean mConstantSize; boolean mComputedConstantSize; int mConstantWidth; int mConstantHeight; int mConstantMinimumWidth; int mConstantMinimumHeight; boolean mCheckedOpacity; int mOpacity; boolean mHaveStateful = false; boolean mCheckedStateful; boolean mStateful; boolean mCheckedConstantState; boolean mCanConstantState; boolean mPaddingChecked = false; boolean mDither = DEFAULT_DITHER; boolean mMutated; int mLayoutDirection; int mEnterFadeDuration; int mExitFadeDuration; DrawableContainerState(DrawableContainerState orig, DrawableContainer owner, Resources res) { mOwner = owner; mRes = res; if (orig != null) { mChangingConfigurations = orig.mChangingConfigurations; mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations; final Drawable[] origDr = orig.mDrawables; mCheckedConstantState = true; mCanConstantState = true; mVariablePadding = orig.mVariablePadding; mConstantSize = orig.mConstantSize; mDither = orig.mDither; mMutated = orig.mMutated; mLayoutDirection = orig.mLayoutDirection; mEnterFadeDuration = orig.mEnterFadeDuration; mExitFadeDuration = orig.mExitFadeDuration; // Cloning the following values may require creating futures. mConstantPadding = orig.getConstantPadding(); mPaddingChecked = true; mConstantWidth = orig.getConstantWidth(); mConstantHeight = orig.getConstantHeight(); mConstantMinimumWidth = orig.getConstantMinimumWidth(); mConstantMinimumHeight = orig.getConstantMinimumHeight(); mComputedConstantSize = true; mOpacity = orig.getOpacity(); mCheckedOpacity = true; mStateful = orig.isStateful(); mCheckedStateful = true; // Postpone cloning children and futures until we're absolutely // sure that we're done computing values for the original state. final Drawable[] origDr = orig.mDrawables; mDrawables = new Drawable[origDr.length]; mNumChildren = orig.mNumChildren; final int N = mNumChildren; for (int i=0; i<N; i++) { if (res != null) { mDrawables[i] = origDr[i].getConstantState().newDrawable(res); final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures; if (origDf != null) { mDrawableFutures = origDf.clone(); } else { mDrawables[i] = origDr[i].getConstantState().newDrawable(); } mDrawables[i].setCallback(owner); mDrawables[i].setLayoutDirection(origDr[i].getLayoutDirection()); mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren); } mCheckedConstantState = mCanConstantState = true; mVariablePadding = orig.mVariablePadding; if (orig.mConstantPadding != null) { mConstantPadding = new Rect(orig.mConstantPadding); final int N = mNumChildren; for (int i = 0; i < N; i++) { if (origDr[i] != null) { mDrawableFutures.put(i, new ConstantStateFuture(origDr[i])); } } mConstantSize = orig.mConstantSize; mComputedConstantSize = orig.mComputedConstantSize; mConstantWidth = orig.mConstantWidth; mConstantHeight = orig.mConstantHeight; mConstantMinimumWidth = orig.mConstantMinimumWidth; mConstantMinimumHeight = orig.mConstantMinimumHeight; mOpacity = orig.mOpacity; mHaveStateful = orig.mHaveStateful; mStateful = orig.mStateful; mDither = orig.mDither; mEnterFadeDuration = orig.mEnterFadeDuration; mExitFadeDuration = orig.mExitFadeDuration; } else { mDrawables = new Drawable[10]; mNumChildren = 0; mCheckedConstantState = mCanConstantState = false; } } Loading @@ -534,7 +550,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mDrawables[pos] = dr; mNumChildren++; mChildrenChangingConfigurations |= dr.getChangingConfigurations(); mHaveStateful = false; mCheckedStateful = false; mCheckedOpacity = false; mConstantPadding = null; mPaddingChecked = false; Loading @@ -547,6 +564,18 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return mDrawables.length; } private final void createAllFutures() { if (mDrawableFutures != null) { final int futureCount = mDrawableFutures.size(); for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) { final int index = mDrawableFutures.keyAt(keyIndex); mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this); } mDrawableFutures = null; } } public final int getChildCount() { return mNumChildren; } Loading @@ -555,24 +584,64 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { * @deprecated Use {@link #getChild} instead. */ public final Drawable[] getChildren() { // Create all futures for backwards compatibility. createAllFutures(); return mDrawables; } public final Drawable getChild(int index) { return mDrawables[index]; final Drawable result = mDrawables[index]; if (result != null) { return result; } // Prepare future drawable if necessary. if (mDrawableFutures != null) { final int keyIndex = mDrawableFutures.indexOfKey(index); if (keyIndex >= 0) { final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this); mDrawables[index] = prepared; mDrawableFutures.removeAt(keyIndex); return prepared; } } return null; } final void setLayoutDirection(int layoutDirection) { // No need to call createAllFutures, since future drawables will // change layout direction when they are prepared. final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (drawables[i] != null) { drawables[i].setLayoutDirection(layoutDirection); } } mLayoutDirection = layoutDirection; } final void mutate() { final int N = getChildCount(); // No need to call createAllFutures, since future drawables will // mutate when they are prepared. final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (drawables[i] != null) drawables[i].mutate(); if (drawables[i] != null) { drawables[i].mutate(); } } /** A boolean value indicating whether to use the maximum padding value of * all frames in the set (false), or to use the padding value of the frame * being shown (true). Default value is false. mMutated = true; } /** * A boolean value indicating whether to use the maximum padding value * of all frames in the set (false), or to use the padding value of the * frame being shown (true). Default value is false. */ public final void setVariablePadding(boolean variable) { mVariablePadding = variable; Loading @@ -582,13 +651,16 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { if (mVariablePadding) { return null; } if (mConstantPadding != null || mPaddingChecked) { if ((mConstantPadding != null) || mPaddingChecked) { return mConstantPadding; } createAllFutures(); Rect r = null; final Rect t = new Rect(); final int N = getChildCount(); final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (drawables[i].getPadding(t)) { Loading @@ -599,6 +671,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { if (t.bottom > r.bottom) r.bottom = t.bottom; } } mPaddingChecked = true; return (mConstantPadding = r); } Loading Loading @@ -646,12 +719,14 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { protected void computeConstantSize() { mComputedConstantSize = true; final int N = getChildCount(); createAllFutures(); final int N = mNumChildren; final Drawable[] drawables = mDrawables; mConstantWidth = mConstantHeight = -1; mConstantMinimumWidth = mConstantMinimumHeight = 0; for (int i = 0; i < N; i++) { Drawable dr = drawables[i]; final Drawable dr = drawables[i]; int s = dr.getIntrinsicWidth(); if (s > mConstantWidth) mConstantWidth = s; s = dr.getIntrinsicHeight(); Loading Loading @@ -680,33 +755,45 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } public final int getOpacity() { final int N = getChildCount(); if (mCheckedOpacity) { return mOpacity; } createAllFutures(); mCheckedOpacity = true; final int N = mNumChildren; final Drawable[] drawables = mDrawables; int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT; for (int i = 1; i < N; i++) { op = Drawable.resolveOpacity(op, drawables[i].getOpacity()); } mOpacity = op; return op; } public final boolean isStateful() { if (mHaveStateful) { if (mCheckedStateful) { return mStateful; } boolean stateful = false; final int N = getChildCount(); createAllFutures(); mCheckedStateful = true; final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (mDrawables[i].isStateful()) { stateful = true; break; if (drawables[i].isStateful()) { mStateful = true; return true; } } mStateful = stateful; mHaveStateful = true; return stateful; mStateful = false; return false; } public void growArray(int oldSize, int newSize) { Loading @@ -716,24 +803,60 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } public synchronized boolean canConstantState() { if (!mCheckedConstantState) { mCanConstantState = true; if (mCheckedConstantState) { return mCanConstantState; } createAllFutures(); mCheckedConstantState = true; final int N = mNumChildren; final Drawable[] drawables = mDrawables; for (int i = 0; i < N; i++) { if (mDrawables[i].getConstantState() == null) { if (drawables[i].getConstantState() == null) { mCanConstantState = false; break; return false; } } mCheckedConstantState = true; mCanConstantState = true; return true; } return mCanConstantState; /** * Class capable of cloning a Drawable from another Drawable's * ConstantState. */ private static class ConstantStateFuture { private final ConstantState mConstantState; private ConstantStateFuture(Drawable source) { mConstantState = source.getConstantState(); } /** * Obtains and prepares the Drawable represented by this future. * * @param state the container into which this future will be placed * @return a prepared Drawable */ public Drawable get(DrawableContainerState state) { final Drawable result = (state.mRes == null) ? mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes); result.setLayoutDirection(state.mLayoutDirection); result.setCallback(state.mOwner); if (state.mMutated) { result.mutate(); } return result; } } } protected void setConstantState(DrawableContainerState state) { protected void setConstantState(DrawableContainerState state) { mDrawableContainerState = state; } }
graphics/java/android/graphics/drawable/StateListDrawable.java +4 −4 Original line number Diff line number Diff line Loading @@ -264,11 +264,11 @@ public class StateListDrawable extends DrawableContainer { /** @hide */ @Override public void setLayoutDirection(int layoutDirection) { final int numStates = getStateCount(); for (int i = 0; i < numStates; i++) { getStateDrawable(i).setLayoutDirection(layoutDirection); } super.setLayoutDirection(layoutDirection); // Let the container handle setting its own layout direction. Otherwise, // we're accessing potentially unused states. mStateListState.setLayoutDirection(layoutDirection); } static final class StateListState extends DrawableContainerState { Loading