DrawableContainer.java revision c80ad99a33ee49d0bac994c1749ff24d243c3862
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19c2974809373697147cbe5754835cc871fb93aef1Dianne Hackbornimport android.content.res.Resources;
2052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme;
2178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Canvas;
2278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.ColorFilter;
23bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milneimport android.graphics.Insets;
2478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PixelFormat;
2578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Rect;
26079e23575024e103358c982152afb7a720ae1a8aDianne Hackbornimport android.os.SystemClock;
27600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglioimport android.util.LayoutDirection;
28f390f770ee570f1f4def41b165cb9492e381be40Alan Viveretteimport android.util.SparseArray;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne/**
3178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A helper class that contains several {@link Drawable}s and selects which one to use.
3278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne *
3378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * You can subclass it to create your own DrawableContainers or directly use one its child classes.
3478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DrawableContainer extends Drawable implements Drawable.Callback {
36079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private static final boolean DEBUG = false;
37079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private static final String TAG = "DrawableContainer";
38211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed
39211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed    /**
40211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * To be proper, we should have a getter for dither (and alpha, etc.)
41211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * so that proxy classes like this can save/restore their delegates'
42211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * values, but we don't have getters. Since we do have setters
43211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * (e.g. setDither), which this proxy forwards on, we have to have some
44211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * default/initial setting.
45211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     *
46211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * The initial setting for dither is now true, since it almost always seems
47211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * to improve the quality at negligible cost.
48211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     */
49211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed    private static final boolean DEFAULT_DITHER = true;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private DrawableContainerState mDrawableContainerState;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mCurrDrawable;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAlpha = 0xFF;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette    /** Whether setAlpha() has been called at least once. */
55729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette    private boolean mHasAlpha;
56729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mCurIndex = -1;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMutated;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    // Animations.
61079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private Runnable mAnimationRunnable;
62079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private long mEnterAnimationEnd;
63079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private long mExitAnimationEnd;
64079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private Drawable mLastDrawable;
65079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
66f68bb66c6ec239790ba18b8d078eb7ab4894fdc3John Spurlock    private Insets mInsets = Insets.NONE;
67600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // overrides from Drawable
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.draw(canvas);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
75079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
76079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.draw(canvas);
77079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.getChangingConfigurations()
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mDrawableContainerState.mChangingConfigurations
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                | mDrawableContainerState.mChildrenChangingConfigurations;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
86f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
87600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio    private boolean needsMirroring() {
88600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio        return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL;
89600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio    }
90600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getPadding(Rect padding) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect r = mDrawableContainerState.getConstantPadding();
94f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio        boolean result;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (r != null) {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            padding.set(r);
97f7a93ef3847258157d144dfefaa5757128cc807dFabrice Di Meglio            result = (r.left | r.top | r.bottom | r.right) != 0;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
99600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            if (mCurrDrawable != null) {
100600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio                result = mCurrDrawable.getPadding(padding);
101600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            } else {
102600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio                result = super.getPadding(padding);
103600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
105600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio        if (needsMirroring()) {
106600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            final int left = padding.left;
107600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            final int right = padding.right;
108600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            padding.left = right;
109600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            padding.right = left;
110600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio        }
111600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio        return result;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1141557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    /**
1151557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     * @hide
1161557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne     */
1171557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    @Override
1187b7578184567f4e4f0740ce935cc192765410ccaPhilip Milne    public Insets getOpticalInsets() {
119600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio        return mInsets;
1201557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    }
1211557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
12434bd56b546bce47422a430d9d7806dc3cb4254bfAlan Viverette        if (!mHasAlpha || mAlpha != alpha) {
12534bd56b546bce47422a430d9d7806dc3cb4254bfAlan Viverette            mHasAlpha = true;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAlpha = alpha;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
128079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mEnterAnimationEnd == 0) {
1295f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(alpha);
130079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
131079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animate(false);
132079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
138b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    public int getAlpha() {
139b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        return mAlpha;
140b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    }
141b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
142b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {
144a41581ed4033004c73115113f45b9844e9b0210fRomain Guy        if (mDrawableContainerState.mDither != dither) {
145a41581ed4033004c73115113f45b9844e9b0210fRomain Guy            mDrawableContainerState.mDither = dither;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
1475f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                mCurrDrawable.mutate().setDither(mDrawableContainerState.mDither);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(ColorFilter cf) {
154729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        mDrawableContainerState.mHasColorFilter = true;
155729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
156d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette        if (mDrawableContainerState.mColorFilter != cf) {
157d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette            mDrawableContainerState.mColorFilter = cf;
158729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
1605f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                mCurrDrawable.mutate().setColorFilter(cf);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
164f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
165079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
166079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * Change the global fade duration when a new drawable is entering
167079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * the scene.
168079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * @param ms The amount of time to fade in milliseconds.
169079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
170079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void setEnterFadeDuration(int ms) {
171079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        mDrawableContainerState.mEnterFadeDuration = ms;
172079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
173f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
174079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
175079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * Change the global fade duration when a new drawable is leaving
176079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * the scene.
177079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * @param ms The amount of time to fade in milliseconds.
178079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
179079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void setExitFadeDuration(int ms) {
180079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        mDrawableContainerState.mExitFadeDuration = ms;
181079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
182f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect bounds) {
185079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
186079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.setBounds(bounds);
187079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.setBounds(bounds);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
192f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isStateful() {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDrawableContainerState.isStateful();
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
197f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1993f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public void setAutoMirrored(boolean mirrored) {
200729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        if (mDrawableContainerState.mAutoMirrored != mirrored) {
201729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            mDrawableContainerState.mAutoMirrored = mirrored;
202729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            if (mCurrDrawable != null) {
203729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
204729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            }
2053f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        }
2063f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
2073f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
2083f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
2093f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public boolean isAutoMirrored() {
2103f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        return mDrawableContainerState.mAutoMirrored;
2113f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
2123f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
2133f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
214079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void jumpToCurrentState() {
215079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        boolean changed = false;
216079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
217079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.jumpToCurrentState();
218079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable = null;
219079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
220079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
221079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mCurrDrawable != null) {
222079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mCurrDrawable.jumpToCurrentState();
223729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            if (mHasAlpha) {
224729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                mCurrDrawable.mutate().setAlpha(mAlpha);
225729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            }
226079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
227079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mExitAnimationEnd != 0) {
228079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitAnimationEnd = 0;
229079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
230079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
231079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mEnterAnimationEnd != 0) {
232079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterAnimationEnd = 0;
233079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
234079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
235079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (changed) {
236079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            invalidateSelf();
237079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
238079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
239079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
240079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    @Override
241c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette    public void setHotspot(float x, float y) {
242307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette        if (mCurrDrawable != null) {
243c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette            mCurrDrawable.setHotspot(x, y);
244307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette        }
245307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette    }
246307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette
247307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette    @Override
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onStateChange(int[] state) {
249079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
250079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mLastDrawable.setState(state);
251079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.setState(state);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) {
260079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
261079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mLastDrawable.setLevel(level);
262079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.setLevel(level);
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantWidth();
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantHeight();
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
284f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumWidth() {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantMinimumWidth();
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0;
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumHeight() {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantMinimumHeight();
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30172146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
302079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void invalidateDrawable(Drawable who) {
303f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
304f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().invalidateDrawable(this);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30872146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
309079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void scheduleDrawable(Drawable who, Runnable what, long when) {
310f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
311f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().scheduleDrawable(this, what, when);
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31572146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
316079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void unscheduleDrawable(Drawable who, Runnable what) {
317f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
318f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().unscheduleDrawable(this, what);
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setVisible(boolean visible, boolean restart) {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = super.setVisible(visible, restart);
325079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
326079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.setVisible(visible, restart);
327079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.setVisible(visible, restart);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
33683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT :
33783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                mDrawableContainerState.getOpacity();
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3405e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    /** @hide */
3415e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    public void setCurrentIndex(int index) {
3425e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette        selectDrawable(index);
3435e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    }
3445e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette
3455e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    /** @hide */
3465e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    public int getCurrentIndex() {
3475e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette        return mCurIndex;
3485e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    }
3495e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette
35078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne    public boolean selectDrawable(int idx) {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (idx == mCurIndex) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
354079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
355079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        final long now = SystemClock.uptimeMillis();
356079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
357079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx
358079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                + ": exit=" + mDrawableContainerState.mExitFadeDuration
359079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                + " enter=" + mDrawableContainerState.mEnterFadeDuration);
360079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
361079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mDrawableContainerState.mExitFadeDuration > 0) {
362079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mLastDrawable != null) {
363079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable.setVisible(false, false);
364079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
366079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable = mCurrDrawable;
367079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration;
368079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            } else {
369079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable = null;
370079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitAnimationEnd = 0;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
372079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else if (mCurrDrawable != null) {
373079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mCurrDrawable.setVisible(false, false);
374079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
375079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
376079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
377f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable d = mDrawableContainerState.getChild(idx);
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable = d;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIndex = idx;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (d != null) {
381600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio                mInsets = d.getOpticalInsets();
3825f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                d.mutate();
383079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mDrawableContainerState.mEnterFadeDuration > 0) {
384079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
385729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                } else if (mHasAlpha) {
386079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    d.setAlpha(mAlpha);
387079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
388729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                if (mDrawableContainerState.mHasColorFilter) {
389729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                    d.setColorFilter(mDrawableContainerState.mColorFilter);
390729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                }
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setVisible(isVisible(), true);
392a41581ed4033004c73115113f45b9844e9b0210fRomain Guy                d.setDither(mDrawableContainerState.mDither);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setState(getState());
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setLevel(getLevel());
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setBounds(getBounds());
396731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio                d.setLayoutDirection(getLayoutDirection());
3973f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
398600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            } else {
399600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio                mInsets = Insets.NONE;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable = null;
403600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglio            mInsets = Insets.NONE;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIndex = -1;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
406079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
407079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) {
408079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mAnimationRunnable == null) {
409079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mAnimationRunnable = new Runnable() {
410079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    @Override public void run() {
411079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                        animate(true);
412079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                        invalidateSelf();
413079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    }
414079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                };
415079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            } else {
416079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                unscheduleSelf(mAnimationRunnable);
417079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
418079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            // Compute first frame and schedule next animation.
419079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            animate(true);
420079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
421079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invalidateSelf();
423079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
426f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
427079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    void animate(boolean schedule) {
428729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        mHasAlpha = true;
429729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
430079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        final long now = SystemClock.uptimeMillis();
431079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        boolean animating = false;
432079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mCurrDrawable != null) {
433079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mEnterAnimationEnd != 0) {
434079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mEnterAnimationEnd <= now) {
4355f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(mAlpha);
436079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mEnterAnimationEnd = 0;
437079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
438079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    int animAlpha = (int)((mEnterAnimationEnd-now)*255)
439079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                            / mDrawableContainerState.mEnterFadeDuration;
440079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha);
4415f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(((255-animAlpha)*mAlpha)/255);
442079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animating = true;
443079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
444079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
445079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else {
446079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterAnimationEnd = 0;
447079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
448079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
449079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mExitAnimationEnd != 0) {
450079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mExitAnimationEnd <= now) {
451079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mLastDrawable.setVisible(false, false);
452079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mLastDrawable = null;
453079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mExitAnimationEnd = 0;
454079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
455079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    int animAlpha = (int)((mExitAnimationEnd-now)*255)
456079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                            / mDrawableContainerState.mExitFadeDuration;
457079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha);
4585f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mLastDrawable.mutate().setAlpha((animAlpha*mAlpha)/255);
459079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animating = true;
460079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
461079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
462079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else {
463079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitAnimationEnd = 0;
464079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
465079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
466079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (schedule && animating) {
467079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            scheduleSelf(mAnimationRunnable, now + 1000/60);
468079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
469079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
470079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getCurrent() {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable;
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
47752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void applyTheme(Theme theme) {
47852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        mDrawableContainerState.applyTheme(theme);
47952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
48052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
48152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
48252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public boolean canApplyTheme() {
48352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return mDrawableContainerState.canApplyTheme();
48452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
48552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
48652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.canConstantState()) {
4896efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais            mDrawableContainerState.mChangingConfigurations = getChangingConfigurations();
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mMutated && super.mutate() == this) {
49872146433322588c1116ee06c27ac758ad09d869cAlan Viverette            mDrawableContainerState.mutate();
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMutated = true;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne    /**
50578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * A ConstantState that can contain several {@link Drawable}s.
50678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     *
50778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * This class was made public to enable testing, and its visibility may change in a future
50878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * release.
50978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     */
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract static class DrawableContainerState extends ConstantState {
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final DrawableContainer mOwner;
512f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        final Resources mRes;
513f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
51452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        Theme mTheme;
51552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
516f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        SparseArray<ConstantStateFuture> mDrawableFutures;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
518f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mChangingConfigurations;
519f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mChildrenChangingConfigurations;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
521f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        Drawable[] mDrawables;
522f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mNumChildren;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
524f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mVariablePadding;
525f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mPaddingChecked;
526f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        Rect mConstantPadding;
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
528f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mConstantSize;
529f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mComputedConstantSize;
530f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantWidth;
531f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantHeight;
532f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantMinimumWidth;
533f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantMinimumHeight;
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
535f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedOpacity;
536f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mOpacity;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
538f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedStateful;
539f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mStateful;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
541f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedConstantState;
542f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCanConstantState;
5435140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy
544f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mDither = DEFAULT_DITHER;
545f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
546f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mMutated;
547f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mLayoutDirection;
548f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
549f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mEnterFadeDuration;
550f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mExitFadeDuration;
551079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
5523f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        boolean mAutoMirrored;
5533f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
554d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette        ColorFilter mColorFilter;
555729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        boolean mHasColorFilter;
556d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette
557c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
558c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                Resources res) {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOwner = owner;
560f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mRes = res;
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (orig != null) {
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChangingConfigurations = orig.mChangingConfigurations;
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
566f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedConstantState = true;
567f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCanConstantState = true;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mVariablePadding = orig.mVariablePadding;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mConstantSize = orig.mConstantSize;
571a41581ed4033004c73115113f45b9844e9b0210fRomain Guy                mDither = orig.mDither;
572f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mMutated = orig.mMutated;
573f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mLayoutDirection = orig.mLayoutDirection;
574079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mEnterFadeDuration = orig.mEnterFadeDuration;
575079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitFadeDuration = orig.mExitFadeDuration;
5763f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                mAutoMirrored = orig.mAutoMirrored;
577d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette                mColorFilter = orig.mColorFilter;
578729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                mHasColorFilter = orig.mHasColorFilter;
579079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
580f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // Cloning the following values may require creating futures.
581f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantPadding = orig.getConstantPadding();
582f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mPaddingChecked = true;
583f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
584f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantWidth = orig.getConstantWidth();
585f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantHeight = orig.getConstantHeight();
586f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantMinimumWidth = orig.getConstantMinimumWidth();
587f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantMinimumHeight = orig.getConstantMinimumHeight();
588f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mComputedConstantSize = true;
589f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
590f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mOpacity = orig.getOpacity();
591f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedOpacity = true;
592f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
593f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mStateful = orig.isStateful();
594f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedStateful = true;
595f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
596f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // Postpone cloning children and futures until we're absolutely
597f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // sure that we're done computing values for the original state.
598f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable[] origDr = orig.mDrawables;
599f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mDrawables = new Drawable[origDr.length];
600f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mNumChildren = orig.mNumChildren;
601f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
602f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures;
603f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (origDf != null) {
604f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures = origDf.clone();
605f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                } else {
606f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
607f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
608f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
609f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int N = mNumChildren;
610f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                for (int i = 0; i < N; i++) {
611f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    if (origDr[i] != null) {
612f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                        mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
613f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    }
614f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDrawables = new Drawable[10];
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNumChildren = 0;
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
620f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
623dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio            return mChangingConfigurations | mChildrenChangingConfigurations;
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final int addChild(Drawable dr) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pos = mNumChildren;
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos >= mDrawables.length) {
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                growArray(pos, pos+10);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dr.setVisible(false, true);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dr.setCallback(mOwner);
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDrawables[pos] = dr;
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mNumChildren++;
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mChildrenChangingConfigurations |= dr.getChangingConfigurations();
639f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedStateful = false;
640f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedOpacity = false;
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantPadding = null;
6435140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            mPaddingChecked = false;
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mComputedConstantSize = false;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return pos;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
64972146433322588c1116ee06c27ac758ad09d869cAlan Viverette        final int getCapacity() {
65072146433322588c1116ee06c27ac758ad09d869cAlan Viverette            return mDrawables.length;
65172146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
65272146433322588c1116ee06c27ac758ad09d869cAlan Viverette
653f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        private final void createAllFutures() {
654f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mDrawableFutures != null) {
655f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int futureCount = mDrawableFutures.size();
656f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) {
657f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    final int index = mDrawableFutures.keyAt(keyIndex);
658f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this);
659f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
660f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
661f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mDrawableFutures = null;
662f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
663f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
664f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
66583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getChildCount() {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mNumChildren;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
66972146433322588c1116ee06c27ac758ad09d869cAlan Viverette        /*
67072146433322588c1116ee06c27ac758ad09d869cAlan Viverette         * @deprecated Use {@link #getChild} instead.
67172146433322588c1116ee06c27ac758ad09d869cAlan Viverette         */
67283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final Drawable[] getChildren() {
673f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // Create all futures for backwards compatibility.
674f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
675f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawables;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
67972146433322588c1116ee06c27ac758ad09d869cAlan Viverette        public final Drawable getChild(int index) {
680f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable result = mDrawables[index];
681f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (result != null) {
682f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return result;
683f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
684f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
685f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // Prepare future drawable if necessary.
686f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mDrawableFutures != null) {
687f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int keyIndex = mDrawableFutures.indexOfKey(index);
688f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (keyIndex >= 0) {
689f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this);
690f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawables[index] = prepared;
691f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures.removeAt(keyIndex);
692f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return prepared;
693f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
694f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
695f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
696f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return null;
697f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
698f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
699f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        final void setLayoutDirection(int layoutDirection) {
700f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // No need to call createAllFutures, since future drawables will
701f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // change layout direction when they are prepared.
702f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
703f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
704f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            for (int i = 0; i < N; i++) {
705f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i] != null) {
706f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    drawables[i].setLayoutDirection(layoutDirection);
707f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
708f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
709f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
710f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mLayoutDirection = layoutDirection;
71172146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
71272146433322588c1116ee06c27ac758ad09d869cAlan Viverette
71352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final void applyTheme(Theme theme) {
71452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // No need to call createAllFutures, since future drawables will
71552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // apply the theme when they are prepared.
71652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final int N = mNumChildren;
71752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final Drawable[] drawables = mDrawables;
71852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            for (int i = 0; i < N; i++) {
71952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (drawables[i] != null) {
72052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    drawables[i].applyTheme(theme);
72152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
72252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
72352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
72452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mTheme = theme;
72552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
72652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
72752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
72852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public boolean canApplyTheme() {
72952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final int N = mNumChildren;
73052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final Drawable[] drawables = mDrawables;
73152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            for (int i = 0; i < N; i++) {
73252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                final Drawable d = drawables[i];
73352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (d != null) {
73452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    if (d.canApplyTheme()) {
73552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        return true;
73652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    }
73752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                } else {
73852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    final ConstantStateFuture future = mDrawableFutures.get(i);
73952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    if (future != null && future.canApplyTheme()) {
74052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        return true;
74152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    }
74252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
74352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
74452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
74552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return false;
74652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
74752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
74872146433322588c1116ee06c27ac758ad09d869cAlan Viverette        final void mutate() {
749f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // No need to call createAllFutures, since future drawables will
750f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // mutate when they are prepared.
751f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
75272146433322588c1116ee06c27ac758ad09d869cAlan Viverette            final Drawable[] drawables = mDrawables;
75372146433322588c1116ee06c27ac758ad09d869cAlan Viverette            for (int i = 0; i < N; i++) {
754f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i] != null) {
755f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    drawables[i].mutate();
756f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
75772146433322588c1116ee06c27ac758ad09d869cAlan Viverette            }
758f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
759f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mMutated = true;
76072146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
76172146433322588c1116ee06c27ac758ad09d869cAlan Viverette
762f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        /**
763f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * A boolean value indicating whether to use the maximum padding value
764f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * of all frames in the set (false), or to use the padding value of the
765f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * frame being shown (true). Default value is false.
766f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         */
76783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final void setVariablePadding(boolean variable) {
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mVariablePadding = variable;
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
77183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final Rect getConstantPadding() {
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mVariablePadding) {
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
775f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
776f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if ((mConstantPadding != null) || mPaddingChecked) {
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mConstantPadding;
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
780f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
781f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
7825140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            Rect r = null;
78383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Rect t = new Rect();
784f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
78583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
78683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 0; i < N; i++) {
78783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                if (drawables[i].getPadding(t)) {
7885140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy                    if (r == null) r = new Rect(0, 0, 0, 0);
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.left > r.left) r.left = t.left;
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.top > r.top) r.top = t.top;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.right > r.right) r.right = t.right;
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.bottom > r.bottom) r.bottom = t.bottom;
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
795f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
7965140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            mPaddingChecked = true;
7975140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            return (mConstantPadding = r);
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final void setConstantSize(boolean constant) {
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantSize = constant;
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final boolean isConstantSize() {
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantSize;
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantWidth() {
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantWidth;
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
81683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantHeight() {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantHeight;
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
82483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantMinimumWidth() {
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantMinimumWidth;
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
83283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantMinimumHeight() {
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantMinimumHeight;
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne        protected void computeConstantSize() {
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mComputedConstantSize = true;
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
843f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
844f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
845f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
84683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
84778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne            mConstantWidth = mConstantHeight = -1;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantMinimumWidth = mConstantMinimumHeight = 0;
84983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 0; i < N; i++) {
850f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable dr = drawables[i];
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int s = dr.getIntrinsicWidth();
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantWidth) mConstantWidth = s;
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getIntrinsicHeight();
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantHeight) mConstantHeight = s;
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getMinimumWidth();
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantMinimumWidth) mConstantMinimumWidth = s;
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getMinimumHeight();
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantMinimumHeight) mConstantMinimumHeight = s;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
862079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final void setEnterFadeDuration(int duration) {
863079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterFadeDuration = duration;
864079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
865079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
866079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final int getEnterFadeDuration() {
867079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mEnterFadeDuration;
868079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
869079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
870079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final void setExitFadeDuration(int duration) {
871079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitFadeDuration = duration;
872079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
873079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
874079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final int getExitFadeDuration() {
875079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mExitFadeDuration;
876079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
877079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
87883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getOpacity() {
879f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedOpacity) {
880f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return mOpacity;
881f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
882f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
883f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
884f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
885f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedOpacity = true;
886f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
887f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
88883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
889f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
89083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 1; i < N; i++) {
89183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
893f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOpacity = op;
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return op;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
89783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final boolean isStateful() {
899f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedStateful) {
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mStateful;
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
902f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
903f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
904f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
905f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedStateful = true;
906f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
907f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
908f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
910f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i].isStateful()) {
911f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mStateful = true;
912f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return true;
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
915f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
916f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mStateful = false;
917f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return false;
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
92083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public void growArray(int oldSize, int newSize) {
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable[] newDrawables = new Drawable[newSize];
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize);
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDrawables = newDrawables;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public synchronized boolean canConstantState() {
927f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedConstantState) {
928f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return mCanConstantState;
929f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
930f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
931f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
932f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
933f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedConstantState = true;
934f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
935f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
936f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
937f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            for (int i = 0; i < N; i++) {
938f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i].getConstantState() == null) {
939f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mCanConstantState = false;
940f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return false;
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
944f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCanConstantState = true;
945f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return true;
946f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
947f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
948f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        /**
949f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * Class capable of cloning a Drawable from another Drawable's
950f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * ConstantState.
951f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         */
952f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        private static class ConstantStateFuture {
953f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            private final ConstantState mConstantState;
954f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
955f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            private ConstantStateFuture(Drawable source) {
956f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantState = source.getConstantState();
957f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
958f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
959f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            /**
960f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * Obtains and prepares the Drawable represented by this future.
961f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             *
962f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * @param state the container into which this future will be placed
963f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * @return a prepared Drawable
964f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             */
965f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            public Drawable get(DrawableContainerState state) {
96652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                final Drawable result;
96752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (state.mRes == null) {
96852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    result = mConstantState.newDrawable();
96952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                } else if (state.mTheme == null) {
97052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    result = mConstantState.newDrawable(state.mRes);
97152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                } else {
97252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    result = mConstantState.newDrawable(state.mRes, state.mTheme);
97352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
974f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                result.setLayoutDirection(state.mLayoutDirection);
975f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                result.setCallback(state.mOwner);
976f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
977f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (state.mMutated) {
978f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    result.mutate();
979f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
980f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
981f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return result;
982f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
98352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
98452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            /**
98552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette             * Whether the constant state wrapped by this future can apply a
98652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette             * theme.
98752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette             */
98852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            public boolean canApplyTheme() {
98952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                return mConstantState.canApplyTheme();
99052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
994f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette    protected void setConstantState(DrawableContainerState state) {
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDrawableContainerState = state;
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
998