DrawableContainer.java revision 8de1494557cf1d00c1c3fce439138a28de7fbd61
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
19b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList;
20c2974809373697147cbe5754835cc871fb93aef1Dianne Hackbornimport android.content.res.Resources;
2152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme;
2278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Canvas;
2378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.ColorFilter;
24bbd51f1e360b22eece1d74bd65c7e6a0b59dee59Philip Milneimport android.graphics.Insets;
2578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.PixelFormat;
2678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunneimport android.graphics.Rect;
27b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode;
28079e23575024e103358c982152afb7a720ae1a8aDianne Hackbornimport android.os.SystemClock;
29600d7dd1c6d9d1ff81b71085eff2a6be50d6f36cFabrice Di Meglioimport android.util.LayoutDirection;
30f390f770ee570f1f4def41b165cb9492e381be40Alan Viveretteimport android.util.SparseArray;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3278aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne/**
3378aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * A helper class that contains several {@link Drawable}s and selects which one to use.
3478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne *
3578aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne * You can subclass it to create your own DrawableContainers or directly use one its child classes.
3678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne */
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DrawableContainer extends Drawable implements Drawable.Callback {
38079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private static final boolean DEBUG = false;
39079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private static final String TAG = "DrawableContainer";
40211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed
41211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed    /**
42211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * To be proper, we should have a getter for dither (and alpha, etc.)
43211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * so that proxy classes like this can save/restore their delegates'
44211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * values, but we don't have getters. Since we do have setters
45211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * (e.g. setDither), which this proxy forwards on, we have to have some
46211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * default/initial setting.
47211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     *
48211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * The initial setting for dither is now true, since it almost always seems
49211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     * to improve the quality at negligible cost.
50211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed     */
51211db4a2874f1a2d0e7a8cb8d33e81fa08801763Mike Reed    private static final boolean DEFAULT_DITHER = true;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private DrawableContainerState mDrawableContainerState;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mCurrDrawable;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAlpha = 0xFF;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette    /** Whether setAlpha() has been called at least once. */
57729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette    private boolean mHasAlpha;
58729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mCurIndex = -1;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMutated;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
62079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    // Animations.
63079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private Runnable mAnimationRunnable;
64079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private long mEnterAnimationEnd;
65079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private long mExitAnimationEnd;
66079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    private Drawable mLastDrawable;
67079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
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() {
1198de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette        if (mCurrDrawable != null) {
1208de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette            return mCurrDrawable.getOpticalInsets();
1218de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette        }
1228de1494557cf1d00c1c3fce439138a28de7fbd61Alan Viverette        return Insets.NONE;
1231557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne    }
1241557fd7809078e421f751efc7d2539b3efdc54b2Philip Milne
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
12734bd56b546bce47422a430d9d7806dc3cb4254bfAlan Viverette        if (!mHasAlpha || mAlpha != alpha) {
12834bd56b546bce47422a430d9d7806dc3cb4254bfAlan Viverette            mHasAlpha = true;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAlpha = alpha;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
131079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mEnterAnimationEnd == 0) {
1325f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(alpha);
133079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
134079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animate(false);
135079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
141b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    public int getAlpha() {
142b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase        return mAlpha;
143b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    }
144b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase
145b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDither(boolean dither) {
147a41581ed4033004c73115113f45b9844e9b0210fRomain Guy        if (mDrawableContainerState.mDither != dither) {
148a41581ed4033004c73115113f45b9844e9b0210fRomain Guy            mDrawableContainerState.mDither = dither;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
1505f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                mCurrDrawable.mutate().setDither(mDrawableContainerState.mDither);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(ColorFilter cf) {
157b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mDrawableContainerState.mHasColorFilter = (cf != null);
158729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
159d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette        if (mDrawableContainerState.mColorFilter != cf) {
160d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette            mDrawableContainerState.mColorFilter = cf;
161729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
1635f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                mCurrDrawable.mutate().setColorFilter(cf);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
167f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
168b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
169b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    public void setTint(ColorStateList tint, Mode tintMode) {
170b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mDrawableContainerState.mHasTint = (tint != null && tintMode != null);
171b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
172b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (mDrawableContainerState.mTint != tint || mDrawableContainerState.mTintMode != tintMode) {
173b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mDrawableContainerState.mTint = tint;
174b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mDrawableContainerState.mTintMode = tintMode;
175b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
176b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            if (mCurrDrawable != null) {
177b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mCurrDrawable.mutate().setTint(tint, tintMode);
178b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            }
179b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
180b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
181b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
182079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
183079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * Change the global fade duration when a new drawable is entering
184079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * the scene.
185079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * @param ms The amount of time to fade in milliseconds.
186079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
187079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void setEnterFadeDuration(int ms) {
188079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        mDrawableContainerState.mEnterFadeDuration = ms;
189079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
190f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
191079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    /**
192079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * Change the global fade duration when a new drawable is leaving
193079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * the scene.
194079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     * @param ms The amount of time to fade in milliseconds.
195079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn     */
196079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void setExitFadeDuration(int ms) {
197079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        mDrawableContainerState.mExitFadeDuration = ms;
198079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
199f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onBoundsChange(Rect bounds) {
202079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
203079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.setBounds(bounds);
204079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.setBounds(bounds);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
209f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isStateful() {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDrawableContainerState.isStateful();
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
214f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2163f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public void setAutoMirrored(boolean mirrored) {
217729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        if (mDrawableContainerState.mAutoMirrored != mirrored) {
218729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            mDrawableContainerState.mAutoMirrored = mirrored;
219729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            if (mCurrDrawable != null) {
220729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
221729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            }
2223f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        }
2233f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
2243f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
2253f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
2263f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    public boolean isAutoMirrored() {
2273f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        return mDrawableContainerState.mAutoMirrored;
2283f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    }
2293f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
2303f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio    @Override
231079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void jumpToCurrentState() {
232079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        boolean changed = false;
233079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
234079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.jumpToCurrentState();
235079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable = null;
236079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
237079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
238079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mCurrDrawable != null) {
239079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mCurrDrawable.jumpToCurrentState();
240729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            if (mHasAlpha) {
241729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                mCurrDrawable.mutate().setAlpha(mAlpha);
242729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette            }
243079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
244079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mExitAnimationEnd != 0) {
245079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitAnimationEnd = 0;
246079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
247079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
248079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mEnterAnimationEnd != 0) {
249079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterAnimationEnd = 0;
250079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            changed = true;
251079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
252079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (changed) {
253079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            invalidateSelf();
254079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
255079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
256079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
257079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    @Override
258c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette    public void setHotspot(float x, float y) {
259307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette        if (mCurrDrawable != null) {
260c80ad99a33ee49d0bac994c1749ff24d243c3862Alan Viverette            mCurrDrawable.setHotspot(x, y);
261307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette        }
262307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette    }
263307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette
264307ad09228ebf70f1b456f5f00540c0126277850Alan Viverette    @Override
26553a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette    public void setHotspotBounds(int left, int top, int right, int bottom) {
26653a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette        if (mCurrDrawable != null) {
26753a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette            mCurrDrawable.setHotspotBounds(left, top, right, bottom);
26853a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette        }
26953a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette    }
27053a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette
27153a3ed7c46c12c2e578d1b1df8b039c6db690eaaAlan Viverette    @Override
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onStateChange(int[] state) {
273079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
274079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mLastDrawable.setState(state);
275079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.setState(state);
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean onLevelChange(int level) {
284079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
285079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mLastDrawable.setLevel(level);
286079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCurrDrawable.setLevel(level);
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicWidth() {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantWidth();
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getIntrinsicWidth() : -1;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getIntrinsicHeight() {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantHeight();
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1;
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
308f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumWidth() {
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantMinimumWidth();
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getMinimumWidth() : 0;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMinimumHeight() {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.isConstantSize()) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState.getConstantMinimumHeight();
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32572146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
326079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void invalidateDrawable(Drawable who) {
327f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
328f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().invalidateDrawable(this);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33272146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
333079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void scheduleDrawable(Drawable who, Runnable what, long when) {
334f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
335f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().scheduleDrawable(this, what, when);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33972146433322588c1116ee06c27ac758ad09d869cAlan Viverette    @Override
340079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    public void unscheduleDrawable(Drawable who, Runnable what) {
341f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy        if (who == mCurrDrawable && getCallback() != null) {
342f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy            getCallback().unscheduleDrawable(this, what);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setVisible(boolean visible, boolean restart) {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = super.setVisible(visible, restart);
349079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
350079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mLastDrawable.setVisible(visible, restart);
351079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurrDrawable != null) {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable.setVisible(visible, restart);
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return changed;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
36083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT :
36183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                mDrawableContainerState.getOpacity();
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3645e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    /** @hide */
3655e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    public void setCurrentIndex(int index) {
3665e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette        selectDrawable(index);
3675e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    }
3685e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette
3695e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    /** @hide */
3705e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    public int getCurrentIndex() {
3715e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette        return mCurIndex;
3725e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette    }
3735e92c95d847a68178cf6099c801f82dcb7e4fa47Alan Viverette
37478aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne    public boolean selectDrawable(int idx) {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (idx == mCurIndex) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
378079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
379079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        final long now = SystemClock.uptimeMillis();
380079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
381079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx
382079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                + ": exit=" + mDrawableContainerState.mExitFadeDuration
383079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                + " enter=" + mDrawableContainerState.mEnterFadeDuration);
384079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
385079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mDrawableContainerState.mExitFadeDuration > 0) {
386079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mLastDrawable != null) {
387079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable.setVisible(false, false);
388079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurrDrawable != null) {
390079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable = mCurrDrawable;
391079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration;
392079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            } else {
393079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mLastDrawable = null;
394079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitAnimationEnd = 0;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
396079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else if (mCurrDrawable != null) {
397079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mCurrDrawable.setVisible(false, false);
398079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
399079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
400079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
401f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable d = mDrawableContainerState.getChild(idx);
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable = d;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIndex = idx;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (d != null) {
4055f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                d.mutate();
406079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mDrawableContainerState.mEnterFadeDuration > 0) {
407079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
408729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                } else if (mHasAlpha) {
409079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    d.setAlpha(mAlpha);
410079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
411729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                if (mDrawableContainerState.mHasColorFilter) {
412729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                    d.setColorFilter(mDrawableContainerState.mColorFilter);
413b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                } else if (mDrawableContainerState.mHasTint) {
414b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                    d.setTint(mDrawableContainerState.mTint, mDrawableContainerState.mTintMode);
415729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setVisible(isVisible(), true);
417a41581ed4033004c73115113f45b9844e9b0210fRomain Guy                d.setDither(mDrawableContainerState.mDither);
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setState(getState());
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setLevel(getLevel());
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                d.setBounds(getBounds());
421731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio                d.setLayoutDirection(getLayoutDirection());
4223f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurrDrawable = null;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIndex = -1;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
428079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
429079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) {
430079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mAnimationRunnable == null) {
431079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mAnimationRunnable = new Runnable() {
432079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    @Override public void run() {
433079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                        animate(true);
434079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                        invalidateSelf();
435079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    }
436079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                };
437079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            } else {
438079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                unscheduleSelf(mAnimationRunnable);
439079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
440079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            // Compute first frame and schedule next animation.
441079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            animate(true);
442079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
443079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invalidateSelf();
445079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
448f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
449079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    void animate(boolean schedule) {
450729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        mHasAlpha = true;
451729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette
452079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        final long now = SystemClock.uptimeMillis();
453079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        boolean animating = false;
454079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mCurrDrawable != null) {
455079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mEnterAnimationEnd != 0) {
456079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mEnterAnimationEnd <= now) {
4575f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(mAlpha);
458079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mEnterAnimationEnd = 0;
459079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
460079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    int animAlpha = (int)((mEnterAnimationEnd-now)*255)
461079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                            / mDrawableContainerState.mEnterFadeDuration;
462079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha);
4635f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mCurrDrawable.mutate().setAlpha(((255-animAlpha)*mAlpha)/255);
464079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animating = true;
465079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
466079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
467079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else {
468079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterAnimationEnd = 0;
469079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
470079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (mLastDrawable != null) {
471079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            if (mExitAnimationEnd != 0) {
472079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                if (mExitAnimationEnd <= now) {
473079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mLastDrawable.setVisible(false, false);
474079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mLastDrawable = null;
475079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    mExitAnimationEnd = 0;
476079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                } else {
477079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    int animAlpha = (int)((mExitAnimationEnd-now)*255)
478079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                            / mDrawableContainerState.mExitFadeDuration;
479079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha);
4805f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy                    mLastDrawable.mutate().setAlpha((animAlpha*mAlpha)/255);
481079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                    animating = true;
482079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                }
483079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            }
484079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        } else {
485079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitAnimationEnd = 0;
486079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
487079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
488079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        if (schedule && animating) {
489079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            scheduleSelf(mAnimationRunnable, now + 1000/60);
490079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
491079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn    }
492079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getCurrent() {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCurrDrawable;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
49952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void applyTheme(Theme theme) {
50052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        mDrawableContainerState.applyTheme(theme);
50152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
50252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
50352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
50452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public boolean canApplyTheme() {
50552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return mDrawableContainerState.canApplyTheme();
50652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
50752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
50852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDrawableContainerState.canConstantState()) {
5116efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais            mDrawableContainerState.mChangingConfigurations = getChangingConfigurations();
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawableContainerState;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable mutate() {
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mMutated && super.mutate() == this) {
52072146433322588c1116ee06c27ac758ad09d869cAlan Viverette            mDrawableContainerState.mutate();
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMutated = true;
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne    /**
52778aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * A ConstantState that can contain several {@link Drawable}s.
52878aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     *
52978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * This class was made public to enable testing, and its visibility may change in a future
53078aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     * release.
53178aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne     */
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract static class DrawableContainerState extends ConstantState {
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final DrawableContainer mOwner;
534f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        final Resources mRes;
535f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
53652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        Theme mTheme;
53752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
538f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        SparseArray<ConstantStateFuture> mDrawableFutures;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
540f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mChangingConfigurations;
541f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mChildrenChangingConfigurations;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
543f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        Drawable[] mDrawables;
544f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mNumChildren;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
546f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mVariablePadding;
547f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mPaddingChecked;
548f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        Rect mConstantPadding;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
550f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mConstantSize;
551f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mComputedConstantSize;
552f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantWidth;
553f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantHeight;
554f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantMinimumWidth;
555f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mConstantMinimumHeight;
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
557f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedOpacity;
558f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mOpacity;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
560f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedStateful;
561f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mStateful;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
563f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCheckedConstantState;
564f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mCanConstantState;
5655140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy
566f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mDither = DEFAULT_DITHER;
567f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
568f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        boolean mMutated;
569f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mLayoutDirection;
570f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
571f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mEnterFadeDuration;
572f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        int mExitFadeDuration;
573079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
5743f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio        boolean mAutoMirrored;
5753f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio
576d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette        ColorFilter mColorFilter;
577729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette        boolean mHasColorFilter;
578d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette
579b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        ColorStateList mTint;
580b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        Mode mTintMode;
581b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        boolean mHasTint;
582b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
583c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
584c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                Resources res) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOwner = owner;
586f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mRes = res;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (orig != null) {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChangingConfigurations = orig.mChangingConfigurations;
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
592f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedConstantState = true;
593f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCanConstantState = true;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mVariablePadding = orig.mVariablePadding;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mConstantSize = orig.mConstantSize;
597a41581ed4033004c73115113f45b9844e9b0210fRomain Guy                mDither = orig.mDither;
598f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mMutated = orig.mMutated;
599f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mLayoutDirection = orig.mLayoutDirection;
600079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mEnterFadeDuration = orig.mEnterFadeDuration;
601079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn                mExitFadeDuration = orig.mExitFadeDuration;
6023f5a90b2fbba2a83a8a2c5babd5d466a5e0ad2aaFabrice Di Meglio                mAutoMirrored = orig.mAutoMirrored;
603d9e788c4f0528e46db4a035cfac043736becb0d1Alan Viverette                mColorFilter = orig.mColorFilter;
604729427d451bc4d4d268335b8dc1ff6404bc1c91eAlan Viverette                mHasColorFilter = orig.mHasColorFilter;
605b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTint = orig.mTint;
606b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTintMode = orig.mTintMode;
607b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mHasTint = orig.mHasTint;
608079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
609f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // Cloning the following values may require creating futures.
610f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantPadding = orig.getConstantPadding();
611f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mPaddingChecked = true;
612f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
613f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantWidth = orig.getConstantWidth();
614f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantHeight = orig.getConstantHeight();
615f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantMinimumWidth = orig.getConstantMinimumWidth();
616f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantMinimumHeight = orig.getConstantMinimumHeight();
617f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mComputedConstantSize = true;
618f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
619f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mOpacity = orig.getOpacity();
620f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedOpacity = true;
621f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
622f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mStateful = orig.isStateful();
623f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mCheckedStateful = true;
624f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
625f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // Postpone cloning children and futures until we're absolutely
626f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                // sure that we're done computing values for the original state.
627f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable[] origDr = orig.mDrawables;
628f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mDrawables = new Drawable[origDr.length];
629f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mNumChildren = orig.mNumChildren;
630f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
631f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures;
632f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (origDf != null) {
633f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures = origDf.clone();
634f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                } else {
635f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
636f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
637f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
638f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int N = mNumChildren;
639f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                for (int i = 0; i < N; i++) {
640f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    if (origDr[i] != null) {
641f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                        mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
642f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    }
643f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDrawables = new Drawable[10];
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNumChildren = 0;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
649f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
652dc25d25333d3fac96dccfb9bd31d2474d6bc2d78Fabrice Di Meglio            return mChangingConfigurations | mChildrenChangingConfigurations;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final int addChild(Drawable dr) {
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pos = mNumChildren;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (pos >= mDrawables.length) {
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                growArray(pos, pos+10);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dr.setVisible(false, true);
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dr.setCallback(mOwner);
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDrawables[pos] = dr;
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mNumChildren++;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mChildrenChangingConfigurations |= dr.getChangingConfigurations();
668f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedStateful = false;
669f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedOpacity = false;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantPadding = null;
6725140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            mPaddingChecked = false;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mComputedConstantSize = false;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return pos;
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
67872146433322588c1116ee06c27ac758ad09d869cAlan Viverette        final int getCapacity() {
67972146433322588c1116ee06c27ac758ad09d869cAlan Viverette            return mDrawables.length;
68072146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
68172146433322588c1116ee06c27ac758ad09d869cAlan Viverette
682f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        private final void createAllFutures() {
683f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mDrawableFutures != null) {
684f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int futureCount = mDrawableFutures.size();
685f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) {
686f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    final int index = mDrawableFutures.keyAt(keyIndex);
687f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this);
688f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
689f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
690f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mDrawableFutures = null;
691f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
692f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
693f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
69483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getChildCount() {
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mNumChildren;
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
69872146433322588c1116ee06c27ac758ad09d869cAlan Viverette        /*
69972146433322588c1116ee06c27ac758ad09d869cAlan Viverette         * @deprecated Use {@link #getChild} instead.
70072146433322588c1116ee06c27ac758ad09d869cAlan Viverette         */
70183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final Drawable[] getChildren() {
702f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // Create all futures for backwards compatibility.
703f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
704f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mDrawables;
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
70872146433322588c1116ee06c27ac758ad09d869cAlan Viverette        public final Drawable getChild(int index) {
709f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable result = mDrawables[index];
710f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (result != null) {
711f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return result;
712f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
713f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
714f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // Prepare future drawable if necessary.
715f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mDrawableFutures != null) {
716f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final int keyIndex = mDrawableFutures.indexOfKey(index);
717f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (keyIndex >= 0) {
718f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this);
719f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawables[index] = prepared;
720f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mDrawableFutures.removeAt(keyIndex);
721f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return prepared;
722f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
723f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
724f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
725f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return null;
726f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
727f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
728f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        final void setLayoutDirection(int layoutDirection) {
729f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // No need to call createAllFutures, since future drawables will
730f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // change layout direction when they are prepared.
731f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
732f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
733f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            for (int i = 0; i < N; i++) {
734f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i] != null) {
735f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    drawables[i].setLayoutDirection(layoutDirection);
736f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
737f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
738f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
739f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mLayoutDirection = layoutDirection;
74072146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
74172146433322588c1116ee06c27ac758ad09d869cAlan Viverette
74252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final void applyTheme(Theme theme) {
74352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // No need to call createAllFutures, since future drawables will
74452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // apply the theme when they are prepared.
74552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final int N = mNumChildren;
74652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final Drawable[] drawables = mDrawables;
74752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            for (int i = 0; i < N; i++) {
74852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (drawables[i] != null) {
74952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    drawables[i].applyTheme(theme);
75052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
75152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
75252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
75352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mTheme = theme;
75452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
75552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
75652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
75752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public boolean canApplyTheme() {
75852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final int N = mNumChildren;
75952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            final Drawable[] drawables = mDrawables;
76052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            for (int i = 0; i < N; i++) {
761b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                final Drawable d = drawables[i];
76252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (d != null) {
76352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    if (d.canApplyTheme()) {
76452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        return true;
76552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    }
76652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                } else {
76752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    final ConstantStateFuture future = mDrawableFutures.get(i);
76852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    if (future != null && future.canApplyTheme()) {
76952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                        return true;
77052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    }
77152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
77252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
77352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
77452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return false;
77552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
77652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
77772146433322588c1116ee06c27ac758ad09d869cAlan Viverette        final void mutate() {
778f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // No need to call createAllFutures, since future drawables will
779f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            // mutate when they are prepared.
780f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
78172146433322588c1116ee06c27ac758ad09d869cAlan Viverette            final Drawable[] drawables = mDrawables;
78272146433322588c1116ee06c27ac758ad09d869cAlan Viverette            for (int i = 0; i < N; i++) {
783f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i] != null) {
784f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    drawables[i].mutate();
785f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
78672146433322588c1116ee06c27ac758ad09d869cAlan Viverette            }
787f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
788f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mMutated = true;
78972146433322588c1116ee06c27ac758ad09d869cAlan Viverette        }
79072146433322588c1116ee06c27ac758ad09d869cAlan Viverette
791f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        /**
792f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * A boolean value indicating whether to use the maximum padding value
793f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * of all frames in the set (false), or to use the padding value of the
794f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * frame being shown (true). Default value is false.
795f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         */
79683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final void setVariablePadding(boolean variable) {
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mVariablePadding = variable;
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final Rect getConstantPadding() {
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mVariablePadding) {
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
804f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
805f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if ((mConstantPadding != null) || mPaddingChecked) {
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mConstantPadding;
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
810f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
8115140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            Rect r = null;
81283b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Rect t = new Rect();
813f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
81483b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
81583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 0; i < N; i++) {
81683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                if (drawables[i].getPadding(t)) {
8175140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy                    if (r == null) r = new Rect(0, 0, 0, 0);
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.left > r.left) r.left = t.left;
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.top > r.top) r.top = t.top;
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.right > r.right) r.right = t.right;
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (t.bottom > r.bottom) r.bottom = t.bottom;
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
824f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
8255140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            mPaddingChecked = true;
8265140141c2637b89ad0d86c3b715459a1e7b92729Romain Guy            return (mConstantPadding = r);
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
82983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final void setConstantSize(boolean constant) {
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantSize = constant;
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
83383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final boolean isConstantSize() {
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantSize;
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
83783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantWidth() {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantWidth;
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantHeight() {
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantHeight;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
85383b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantMinimumWidth() {
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantMinimumWidth;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
86183b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getConstantMinimumHeight() {
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mComputedConstantSize) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                computeConstantSize();
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mConstantMinimumHeight;
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
86978aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne        protected void computeConstantSize() {
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mComputedConstantSize = true;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
872f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
873f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
874f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
87583b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
87678aaa97b77d56e35e994611406deb398eb9005dbGilles Debunne            mConstantWidth = mConstantHeight = -1;
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mConstantMinimumWidth = mConstantMinimumHeight = 0;
87883b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 0; i < N; i++) {
879f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                final Drawable dr = drawables[i];
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int s = dr.getIntrinsicWidth();
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantWidth) mConstantWidth = s;
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getIntrinsicHeight();
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantHeight) mConstantHeight = s;
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getMinimumWidth();
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantMinimumWidth) mConstantMinimumWidth = s;
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s = dr.getMinimumHeight();
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s > mConstantMinimumHeight) mConstantMinimumHeight = s;
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
891079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final void setEnterFadeDuration(int duration) {
892079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mEnterFadeDuration = duration;
893079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
894079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
895079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final int getEnterFadeDuration() {
896079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mEnterFadeDuration;
897079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
898079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
899079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final void setExitFadeDuration(int duration) {
900079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            mExitFadeDuration = duration;
901079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
902079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
903079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        public final int getExitFadeDuration() {
904079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn            return mExitFadeDuration;
905079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn        }
906079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn
90783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public final int getOpacity() {
908f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedOpacity) {
909f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return mOpacity;
910f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
911f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
912f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
913f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
914f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedOpacity = true;
915f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
916f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
91783b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            final Drawable[] drawables = mDrawables;
918f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
91983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy            for (int i = 1; i < N; i++) {
92083b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy                op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
922f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mOpacity = op;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return op;
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
92683b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final boolean isStateful() {
928f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedStateful) {
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mStateful;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
931f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
932f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
933f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
934f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedStateful = true;
935f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
936f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
937f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < N; i++) {
939f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i].isStateful()) {
940f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mStateful = true;
941f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return true;
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
944f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
945f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mStateful = false;
946f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return false;
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
94983b2107c4d2f07f46b6ae663115421749486f8b1Romain Guy        public void growArray(int oldSize, int newSize) {
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable[] newDrawables = new Drawable[newSize];
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize);
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDrawables = newDrawables;
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public synchronized boolean canConstantState() {
956f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            if (mCheckedConstantState) {
957f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return mCanConstantState;
958f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
959f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
960f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            createAllFutures();
961f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
962f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCheckedConstantState = true;
963f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
964f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final int N = mNumChildren;
965f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            final Drawable[] drawables = mDrawables;
966f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            for (int i = 0; i < N; i++) {
967f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (drawables[i].getConstantState() == null) {
968f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    mCanConstantState = false;
969f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    return false;
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
973f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            mCanConstantState = true;
974f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            return true;
975f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        }
976f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
977f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        /**
978f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * Class capable of cloning a Drawable from another Drawable's
979f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         * ConstantState.
980f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette         */
981f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette        private static class ConstantStateFuture {
982f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            private final ConstantState mConstantState;
983f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
984f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            private ConstantStateFuture(Drawable source) {
985f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                mConstantState = source.getConstantState();
986f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
987f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
988f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            /**
989f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * Obtains and prepares the Drawable represented by this future.
990f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             *
991f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * @param state the container into which this future will be placed
992f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             * @return a prepared Drawable
993f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette             */
994f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            public Drawable get(DrawableContainerState state) {
99552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                final Drawable result;
99652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                if (state.mRes == null) {
99752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    result = mConstantState.newDrawable();
99852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                } else if (state.mTheme == null) {
99952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    result = mConstantState.newDrawable(state.mRes);
100052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                } else {
100152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                    result = mConstantState.newDrawable(state.mRes, state.mTheme);
100252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                }
1003f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                result.setLayoutDirection(state.mLayoutDirection);
1004f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                result.setCallback(state.mOwner);
1005f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1006f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                if (state.mMutated) {
1007f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                    result.mutate();
1008f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                }
1009f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette
1010f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette                return result;
1011f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette            }
101252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
101352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            /**
101452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette             * Whether the constant state wrapped by this future can apply a
101552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette             * theme.
101652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette             */
101752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            public boolean canApplyTheme() {
101852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette                return mConstantState.canApplyTheme();
101952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            }
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1023f390f770ee570f1f4def41b165cb9492e381be40Alan Viverette    protected void setConstantState(DrawableContainerState state) {
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDrawableContainerState = state;
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1027