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 1980756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt; 203f873d86441c30f5d45640a9f70b3b7331985c90Chris Craikimport android.annotation.NonNull; 21ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viveretteimport android.content.pm.ActivityInfo.Config; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.*; 23b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 24b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 2652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 29dfab363807b3b44be4032e410f016e0a0d018426Romain Guyimport android.view.ViewDebug; 3052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 3152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport com.android.internal.R; 3252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3995930e13faac8c17dabfaa1478089baa772f091bRomain Guy * A specialized Drawable that fills the Canvas with a specified color. 4095930e13faac8c17dabfaa1478089baa772f091bRomain Guy * Note that a ColorDrawable ignores the ColorFilter. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>It can be defined in an XML file with the <code><color></code> element.</p> 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#ColorDrawable_color 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ColorDrawable extends Drawable { 47b846b58f7a27f19431bf0af3f39a514ad4761690Chris Craik private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 48b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 49dfab363807b3b44be4032e410f016e0a0d018426Romain Guy @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_") 5052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private ColorState mColorState; 51b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 52b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 535f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy private boolean mMutated; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new black ColorDrawable. 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorDrawable() { 5952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mColorState = new ColorState(); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new ColorDrawable with the specified color. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param color The color to draw. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6780756e38882720860db52f1fcc21fa1505a02abfTor Norbye public ColorDrawable(@ColorInt int color) { 6852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mColorState = new ColorState(); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setColor(color); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 74ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 7545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return super.getChangingConfigurations() | mColorState.getChangingConfigurations(); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 785f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy /** 795f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy * A mutable BitmapDrawable still shares its Bitmap with any other Drawable 805f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy * that comes from the same resource. 815f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy * 825f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy * @return This drawable. 835f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy */ 845f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy @Override 855f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy public Drawable mutate() { 865f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy if (!mMutated && super.mutate() == this) { 8752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mColorState = new ColorState(mColorState); 885f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy mMutated = true; 895f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy } 905f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy return this; 915f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy } 925f49c3023a512efbef8bc9515d310c7a72be4af2Romain Guy 93727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 94727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 95727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 96727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 97727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 98727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 99727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 100727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 103b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final ColorFilter colorFilter = mPaint.getColorFilter(); 104b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null || mTintFilter != null) { 105b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (colorFilter == null) { 106b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mPaint.setColorFilter(mTintFilter); 107b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 108b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 10952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mPaint.setColor(mColorState.mUseColor); 11095930e13faac8c17dabfaa1478089baa772f091bRomain Guy canvas.drawRect(getBounds(), mPaint); 111b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 112b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Restore original color filter. 113b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mPaint.setColorFilter(colorFilter); 11495930e13faac8c17dabfaa1478089baa772f091bRomain Guy } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11870d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase * Gets the drawable's color value. 11970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase * 12070d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase * @return int The color to draw. 12170d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase */ 12280756e38882720860db52f1fcc21fa1505a02abfTor Norbye @ColorInt 12370d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase public int getColor() { 12452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return mColorState.mUseColor; 12570d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase } 12670d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase 12770d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase /** 12852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Sets the drawable's color value. This action will clobber the results of 12952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * prior calls to {@link #setAlpha(int)} on this object, which side-affected 13052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * the underlying color. 13170d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase * 13270d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase * @param color The color to draw. 13370d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase */ 13480756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColor(@ColorInt int color) { 13552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (mColorState.mBaseColor != color || mColorState.mUseColor != color) { 13652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mColorState.mBaseColor = mColorState.mUseColor = color; 1379891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 1389891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 13970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase } 14070d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase 14170d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase /** 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the alpha value of this drawable's color. 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A value between 0 and 255. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 146b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAlpha() { 14852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return mColorState.mUseColor >>> 24; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the color's alpha value. 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param alpha The alpha value to set, between 0 and 255. 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alpha += alpha >> 7; // make it 0..256 15952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int baseAlpha = mColorState.mBaseColor >>> 24; 16052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int useAlpha = baseAlpha * alpha >> 8; 16152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int useColor = (mColorState.mBaseColor << 8 >>> 8) | (useAlpha << 24); 16252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (mColorState.mUseColor != useColor) { 16352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mColorState.mUseColor = useColor; 16441bff38d3060dbcb55133cedaf5d962c3082efc2Chet Haase invalidateSelf(); 16541bff38d3060dbcb55133cedaf5d962c3082efc2Chet Haase } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 168cda212d79d449468384cc7744878b8c99984059cJeff Brown /** 169b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette * Sets the color filter applied to this color. 170b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette * <p> 171955d8d69ea6caabce1461dc25b339b9bf9dc61a6Dianne Hackborn * Only supported on version {@link android.os.Build.VERSION_CODES#LOLLIPOP} and 172b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette * above. Calling this method has no effect on earlier versions. 173cda212d79d449468384cc7744878b8c99984059cJeff Brown * 174b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette * @see android.graphics.drawable.Drawable#setColorFilter(ColorFilter) 175cda212d79d449468384cc7744878b8c99984059cJeff Brown */ 17652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter colorFilter) { 178b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mPaint.setColorFilter(colorFilter); 179b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 180b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 181b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 182a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintList(ColorStateList tint) { 183a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mColorState.mTint = tint; 184a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, mColorState.mTintMode); 185a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette invalidateSelf(); 186a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 187b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 188a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette @Override 189a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintMode(Mode tintMode) { 190a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mColorState.mTintMode = tintMode; 191a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, tintMode); 192a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette invalidateSelf(); 193b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 194b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 195b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 196b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 197b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final ColorState state = mColorState; 198b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 199b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 200b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 201b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 202b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 203b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 204b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 205b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 206b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette public boolean isStateful() { 20713d965485e5ca1355071eb0f04c4cd2683c371bfAlan Viverette return mColorState.mTint != null && mColorState.mTint.isStateful(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 212b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (mTintFilter != null || mPaint.getColorFilter() != null) { 213b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return PixelFormat.TRANSLUCENT; 214b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 215b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 21652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette switch (mColorState.mUseColor >>> 24) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 255: 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PixelFormat.OPAQUE; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PixelFormat.TRANSPARENT; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PixelFormat.TRANSLUCENT; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2263f873d86441c30f5d45640a9f70b3b7331985c90Chris Craik public void getOutline(@NonNull Outline outline) { 2273f873d86441c30f5d45640a9f70b3b7331985c90Chris Craik outline.setRect(getBounds()); 2283f873d86441c30f5d45640a9f70b3b7331985c90Chris Craik outline.setAlpha(getAlpha() / 255.0f); 2293f873d86441c30f5d45640a9f70b3b7331985c90Chris Craik } 2303f873d86441c30f5d45640a9f70b3b7331985c90Chris Craik 2313f873d86441c30f5d45640a9f70b3b7331985c90Chris Craik @Override 23252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 23452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette super.inflate(r, parser, attrs, theme); 23552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 236b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ColorDrawable); 2378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 23852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 23945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 24045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(r); 24152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 2448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette * Updates the constant state from the values in the typed array. 24552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 2468e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 24752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final ColorState state = mColorState; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 2508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 2518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 25252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 2538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2558e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mBaseColor = a.getColor(R.styleable.ColorDrawable_color, state.mBaseColor); 2568e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mUseColor = state.mBaseColor; 25752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 25852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 25952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 260419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette public boolean canApplyTheme() { 261419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette return mColorState.canApplyTheme() || super.canApplyTheme(); 262419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette } 263419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette 264419aa7ad14926a30220aa3b71d045855ea54040aAlan Viverette @Override 26552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void applyTheme(Theme t) { 26652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette super.applyTheme(t); 26752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 26852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final ColorState state = mColorState; 26945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state == null) { 2708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 27152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 27252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 27345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mThemeAttrs != null) { 27445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ColorDrawable); 27545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateStateFromTypedArray(a); 27645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette a.recycle(); 27745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 27845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 27945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mTint != null && state.mTint.canApplyTheme()) { 280e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mTint = state.mTint.obtainForTheme(t); 28145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 28245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 28345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(t.getResources()); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 28852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette return mColorState; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class ColorState extends ConstantState { 292b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette int[] mThemeAttrs; 29370d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase int mBaseColor; // base color, independent of setAlpha() 294dfab363807b3b44be4032e410f016e0a0d018426Romain Guy @ViewDebug.ExportedProperty 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mUseColor; // basecolor modulated by setAlpha() 296ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette @Config int mChangingConfigurations; 297607bd848269fb802550e63aa61945790616f97a7Alan Viverette ColorStateList mTint = null; 298607bd848269fb802550e63aa61945790616f97a7Alan Viverette Mode mTintMode = DEFAULT_TINT_MODE; 29952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 30052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette ColorState() { 30152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Empty constructor. 30252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorState(ColorState state) { 305b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mThemeAttrs = state.mThemeAttrs; 30652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mBaseColor = state.mBaseColor; 30752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mUseColor = state.mUseColor; 30852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mChangingConfigurations = state.mChangingConfigurations; 309b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = state.mTint; 310b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = state.mTintMode; 31152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 31252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 31352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 31452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 31545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mThemeAttrs != null 31645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || (mTint != null && mTint.canApplyTheme()); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 32145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return new ColorDrawable(this, null); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 325c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public Drawable newDrawable(Resources res) { 32645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return new ColorDrawable(this, res); 327c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 328c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn 329c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn @Override 330ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 331e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mChangingConfigurations 332e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mTint != null ? mTint.getChangingConfigurations() : 0); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 33645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private ColorDrawable(ColorState state, Resources res) { 33717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette mColorState = state; 33845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 33945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(res); 34045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 34145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 34245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 34345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Initializes local dynamic properties from state. This should be called 34445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * after significant state changes, e.g. from the One True Constructor and 34545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * after inflating or applying a theme. 34645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 34745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private void updateLocalState(Resources r) { 34845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, mColorState.mTintMode); 34952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 351