1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.graphics.drawable; 18 19 import android.graphics.*; 20 import android.content.res.Resources; 21 import android.content.res.TypedArray; 22 import android.util.AttributeSet; 23 import android.view.ViewDebug; 24 import org.xmlpull.v1.XmlPullParser; 25 import org.xmlpull.v1.XmlPullParserException; 26 27 import java.io.IOException; 28 29 /** 30 * A specialized Drawable that fills the Canvas with a specified color. 31 * Note that a ColorDrawable ignores the ColorFilter. 32 * 33 * <p>It can be defined in an XML file with the <code><color></code> element.</p> 34 * 35 * @attr ref android.R.styleable#ColorDrawable_color 36 */ 37 public class ColorDrawable extends Drawable { 38 @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_") 39 private ColorState mState; 40 private final Paint mPaint = new Paint(); 41 private boolean mMutated; 42 43 /** 44 * Creates a new black ColorDrawable. 45 */ 46 public ColorDrawable() { 47 this(null); 48 } 49 50 /** 51 * Creates a new ColorDrawable with the specified color. 52 * 53 * @param color The color to draw. 54 */ 55 public ColorDrawable(int color) { 56 this(null); 57 setColor(color); 58 } 59 60 private ColorDrawable(ColorState state) { 61 mState = new ColorState(state); 62 } 63 64 @Override 65 public int getChangingConfigurations() { 66 return super.getChangingConfigurations() | mState.mChangingConfigurations; 67 } 68 69 /** 70 * A mutable BitmapDrawable still shares its Bitmap with any other Drawable 71 * that comes from the same resource. 72 * 73 * @return This drawable. 74 */ 75 @Override 76 public Drawable mutate() { 77 if (!mMutated && super.mutate() == this) { 78 mState = new ColorState(mState); 79 mMutated = true; 80 } 81 return this; 82 } 83 84 @Override 85 public void draw(Canvas canvas) { 86 if ((mState.mUseColor >>> 24) != 0) { 87 mPaint.setColor(mState.mUseColor); 88 canvas.drawRect(getBounds(), mPaint); 89 } 90 } 91 92 /** 93 * Gets the drawable's color value. 94 * 95 * @return int The color to draw. 96 */ 97 public int getColor() { 98 return mState.mUseColor; 99 } 100 101 /** 102 * Sets the drawable's color value. This action will clobber the results of prior calls to 103 * {@link #setAlpha(int)} on this object, which side-affected the underlying color. 104 * 105 * @param color The color to draw. 106 */ 107 public void setColor(int color) { 108 if (mState.mBaseColor != color || mState.mUseColor != color) { 109 invalidateSelf(); 110 mState.mBaseColor = mState.mUseColor = color; 111 } 112 } 113 114 /** 115 * Returns the alpha value of this drawable's color. 116 * 117 * @return A value between 0 and 255. 118 */ 119 @Override 120 public int getAlpha() { 121 return mState.mUseColor >>> 24; 122 } 123 124 /** 125 * Sets the color's alpha value. 126 * 127 * @param alpha The alpha value to set, between 0 and 255. 128 */ 129 public void setAlpha(int alpha) { 130 alpha += alpha >> 7; // make it 0..256 131 int baseAlpha = mState.mBaseColor >>> 24; 132 int useAlpha = baseAlpha * alpha >> 8; 133 int oldUseColor = mState.mUseColor; 134 mState.mUseColor = (mState.mBaseColor << 8 >>> 8) | (useAlpha << 24); 135 if (oldUseColor != mState.mUseColor) { 136 invalidateSelf(); 137 } 138 } 139 140 /** 141 * Setting a color filter on a ColorDrawable has no effect. 142 * 143 * @param colorFilter Ignore. 144 */ 145 public void setColorFilter(ColorFilter colorFilter) { 146 } 147 148 public int getOpacity() { 149 switch (mState.mUseColor >>> 24) { 150 case 255: 151 return PixelFormat.OPAQUE; 152 case 0: 153 return PixelFormat.TRANSPARENT; 154 } 155 return PixelFormat.TRANSLUCENT; 156 } 157 158 @Override 159 public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) 160 throws XmlPullParserException, IOException { 161 super.inflate(r, parser, attrs); 162 163 TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.ColorDrawable); 164 165 int color = mState.mBaseColor; 166 color = a.getColor(com.android.internal.R.styleable.ColorDrawable_color, color); 167 mState.mBaseColor = mState.mUseColor = color; 168 169 a.recycle(); 170 } 171 172 @Override 173 public ConstantState getConstantState() { 174 mState.mChangingConfigurations = getChangingConfigurations(); 175 return mState; 176 } 177 178 final static class ColorState extends ConstantState { 179 int mBaseColor; // base color, independent of setAlpha() 180 @ViewDebug.ExportedProperty 181 int mUseColor; // basecolor modulated by setAlpha() 182 int mChangingConfigurations; 183 184 ColorState(ColorState state) { 185 if (state != null) { 186 mBaseColor = state.mBaseColor; 187 mUseColor = state.mUseColor; 188 mChangingConfigurations = state.mChangingConfigurations; 189 } 190 } 191 192 @Override 193 public Drawable newDrawable() { 194 return new ColorDrawable(this); 195 } 196 197 @Override 198 public Drawable newDrawable(Resources res) { 199 return new ColorDrawable(this); 200 } 201 202 @Override 203 public int getChangingConfigurations() { 204 return mChangingConfigurations; 205 } 206 } 207 } 208