ColorDrawable.java revision 607bd848269fb802550e63aa61945790616f97a7
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 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
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.*;
20b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode;
21b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
2352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
26dfab363807b3b44be4032e410f016e0a0d018426Romain Guyimport android.view.ViewDebug;
2752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
2852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport com.android.internal.R;
2952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
3695930e13faac8c17dabfaa1478089baa772f091bRomain Guy * A specialized Drawable that fills the Canvas with a specified color.
3795930e13faac8c17dabfaa1478089baa772f091bRomain Guy * Note that a ColorDrawable ignores the ColorFilter.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>It can be defined in an XML file with the <code>&lt;color></code> element.</p>
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#ColorDrawable_color
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ColorDrawable extends Drawable {
44b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    private final Paint mPaint = new Paint();
45b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
46dfab363807b3b44be4032e410f016e0a0d018426Romain Guy    @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
4752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private ColorState mColorState;
48b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    private PorterDuffColorFilter mTintFilter;
49b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
505f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy    private boolean mMutated;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates a new black ColorDrawable.
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ColorDrawable() {
5652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        mColorState = new ColorState();
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates a new ColorDrawable with the specified color.
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color The color to draw.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ColorDrawable(int color) {
6552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        mColorState = new ColorState();
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        setColor(color);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getChangingConfigurations() {
7252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return super.getChangingConfigurations() | mColorState.mChangingConfigurations;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
755f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy    /**
765f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy     * A mutable BitmapDrawable still shares its Bitmap with any other Drawable
775f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy     * that comes from the same resource.
785f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy     *
795f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy     * @return This drawable.
805f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy     */
815f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy    @Override
825f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy    public Drawable mutate() {
835f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy        if (!mMutated && super.mutate() == this) {
8452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mColorState = new ColorState(mColorState);
855f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy            mMutated = true;
865f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy        }
875f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy        return this;
885f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy    }
895f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
92b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final ColorFilter colorFilter = mPaint.getColorFilter();
93b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null || mTintFilter != null) {
94b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            if (colorFilter == null) {
95b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mPaint.setColorFilter(mTintFilter);
96b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            }
97b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
9852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mPaint.setColor(mColorState.mUseColor);
9995930e13faac8c17dabfaa1478089baa772f091bRomain Guy            canvas.drawRect(getBounds(), mPaint);
100b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
101b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Restore original color filter.
102b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mPaint.setColorFilter(colorFilter);
10395930e13faac8c17dabfaa1478089baa772f091bRomain Guy        }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10770d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     * Gets the drawable's color value.
10870d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     *
10970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     * @return int The color to draw.
11070d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     */
11170d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase    public int getColor() {
11252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return mColorState.mUseColor;
11370d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase    }
11470d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase
11570d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase    /**
11652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * Sets the drawable's color value. This action will clobber the results of
11752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * prior calls to {@link #setAlpha(int)} on this object, which side-affected
11852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     * the underlying color.
11970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     *
12070d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     * @param color The color to draw.
12170d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase     */
12270d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase    public void setColor(int color) {
12352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (mColorState.mBaseColor != color || mColorState.mUseColor != color) {
12452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mColorState.mBaseColor = mColorState.mUseColor = color;
1259891e1fce5f29d0421d34aa481037417bd70853dChet Haase            invalidateSelf();
1269891e1fce5f29d0421d34aa481037417bd70853dChet Haase        }
12770d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase    }
12870d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase
12970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase    /**
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the alpha value of this drawable's color.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A value between 0 and 255.
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
134b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase    @Override
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getAlpha() {
13652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return mColorState.mUseColor >>> 24;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the color's alpha value.
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param alpha The alpha value to set, between 0 and 255.
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAlpha(int alpha) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        alpha += alpha >> 7;   // make it 0..256
14752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int baseAlpha = mColorState.mBaseColor >>> 24;
14852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int useAlpha = baseAlpha * alpha >> 8;
14952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final int useColor = (mColorState.mBaseColor << 8 >>> 8) | (useAlpha << 24);
15052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (mColorState.mUseColor != useColor) {
15152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mColorState.mUseColor = useColor;
15241bff38d3060dbcb55133cedaf5d962c3082efc2Chet Haase            invalidateSelf();
15341bff38d3060dbcb55133cedaf5d962c3082efc2Chet Haase        }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
156cda212d79d449468384cc7744878b8c99984059cJeff Brown    /**
157b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette     * Sets the color filter applied to this color.
158b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette     * <p>
159b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette     * Only supported on version {@link android.os.Build.VERSION_CODES#L} and
160b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette     * above. Calling this method has no effect on earlier versions.
161cda212d79d449468384cc7744878b8c99984059cJeff Brown     *
162b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette     * @see android.graphics.drawable.Drawable#setColorFilter(ColorFilter)
163cda212d79d449468384cc7744878b8c99984059cJeff Brown     */
16452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setColorFilter(ColorFilter colorFilter) {
166b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mPaint.setColorFilter(colorFilter);
167b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
168b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
169b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
170a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    public void setTintList(ColorStateList tint) {
171a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        mColorState.mTint = tint;
172a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, tint, mColorState.mTintMode);
173a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        invalidateSelf();
174a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    }
175b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
176a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    @Override
177a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    public void setTintMode(Mode tintMode) {
178a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        mColorState.mTintMode = tintMode;
179a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, tintMode);
180a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        invalidateSelf();
181b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
182b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
183b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
184b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    protected boolean onStateChange(int[] stateSet) {
185b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final ColorState state = mColorState;
186b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (state.mTint != null && state.mTintMode != null) {
187b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
188b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            return true;
189b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
190b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        return false;
191b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
192b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
193b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
194b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    public boolean isStateful() {
19513d965485e5ca1355071eb0f04c4cd2683c371bfAlan Viverette        return mColorState.mTint != null && mColorState.mTint.isStateful();
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getOpacity() {
200b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (mTintFilter != null || mPaint.getColorFilter() != null) {
201b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            return PixelFormat.TRANSLUCENT;
202b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
203b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
20452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        switch (mColorState.mUseColor >>> 24) {
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 255:
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return PixelFormat.OPAQUE;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case 0:
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return PixelFormat.TRANSPARENT;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PixelFormat.TRANSLUCENT;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
21452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws XmlPullParserException, IOException {
21652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        super.inflate(r, parser, attrs, theme);
21752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
218b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ColorDrawable);
2198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        updateStateFromTypedArray(a);
22052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        a.recycle();
22152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    /**
2248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette     * Updates the constant state from the values in the typed array.
22552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette     */
2268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette    private void updateStateFromTypedArray(TypedArray a) {
22752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final ColorState state = mColorState;
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
2308e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mChangingConfigurations |= a.getChangingConfigurations();
2318e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
23252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        // Extract the theme attributes, if any.
2338e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mThemeAttrs = a.extractThemeAttrs();
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mBaseColor = a.getColor(R.styleable.ColorDrawable_color, state.mBaseColor);
2368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mUseColor = state.mBaseColor;
23752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
23852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
23952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    @Override
24052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    public void applyTheme(Theme t) {
24152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        super.applyTheme(t);
24252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
24352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        final ColorState state = mColorState;
2448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        if (state == null || state.mThemeAttrs == null) {
2458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            return;
24652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
24752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
2488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ColorDrawable);
2498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        updateStateFromTypedArray(a);
2508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        a.recycle();
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ConstantState getConstantState() {
25552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        return mColorState;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final static class ColorState extends ConstantState {
259b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        int[] mThemeAttrs;
26070d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase        int mBaseColor; // base color, independent of setAlpha()
261dfab363807b3b44be4032e410f016e0a0d018426Romain Guy        @ViewDebug.ExportedProperty
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mUseColor;  // basecolor modulated by setAlpha()
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mChangingConfigurations;
264607bd848269fb802550e63aa61945790616f97a7Alan Viverette        ColorStateList mTint = null;
265607bd848269fb802550e63aa61945790616f97a7Alan Viverette        Mode mTintMode = DEFAULT_TINT_MODE;
26652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
26752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        ColorState() {
26852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            // Empty constructor.
26952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorState(ColorState state) {
272b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mThemeAttrs = state.mThemeAttrs;
27352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mBaseColor = state.mBaseColor;
27452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mUseColor = state.mUseColor;
27552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mChangingConfigurations = state.mChangingConfigurations;
276b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTint = state.mTint;
277b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintMode = state.mTintMode;
27852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
27952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
28052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
28152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public boolean canApplyTheme() {
28252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return mThemeAttrs != null;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Drawable newDrawable() {
28752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return new ColorDrawable(this, null, null);
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
291c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        public Drawable newDrawable(Resources res) {
29252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return new ColorDrawable(this, res, null);
29352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
29452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
29552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        @Override
29652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        public Drawable newDrawable(Resources res, Theme theme) {
29752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            return new ColorDrawable(this, res, theme);
298c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        }
299c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn
300c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        @Override
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getChangingConfigurations() {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mChangingConfigurations;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
30552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
30652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    private ColorDrawable(ColorState state, Resources res, Theme theme) {
30752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        if (theme != null && state.canApplyTheme()) {
30852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mColorState = new ColorState(state);
30952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            applyTheme(theme);
31052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        } else {
31152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette            mColorState = state;
31252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette        }
31352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette
314b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
31552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette    }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
317