FileDocCategorySizeDatePackage
ColorStateList.javaAPI DocAndroid 5.1 API14975Thu Mar 12 22:22:10 GMT 2015android.content.res

ColorStateList

public class ColorStateList extends Object implements android.os.Parcelable
Lets you map {@link android.view.View} state sets to colors. {@link android.content.res.ColorStateList}s are created from XML resource files defined in the "color" subdirectory directory of an application's resource directory. The XML file contains a single "selector" element with a number of "item" elements inside. For example:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:color="@color/testcolor1"/>
<item android:state_pressed="true" android:state_enabled="false" android:color="@color/testcolor2" />
<item android:state_enabled="false" android:color="@color/testcolor3" />
<item android:color="@color/testcolor5"/>
</selector>
This defines a set of state spec / color pairs where each state spec specifies a set of states that a view must either be in or not be in and the color specifies the color associated with that spec. The list of state specs will be processed in order of the items in the XML file. An item with no state spec is considered to match any set of states and is generally useful as a final item to be used as a default. Note that if you have such an item before any other items in the list then any subsequent items will end up being ignored.

For more information, see the guide to Color State List Resource.

Fields Summary
private int[]
mStateSpecs
private int[]
mColors
private int
mDefaultColor
private static final int[]
EMPTY
private static final android.util.SparseArray
sCache
public static final Parcelable.Creator
CREATOR
Constructors Summary
private ColorStateList()


       
public ColorStateList(int[] states, int[] colors)
Creates a ColorStateList that returns the specified mapping from states to colors.

        mStateSpecs = states;
        mColors = colors;

        if (states.length > 0) {
            mDefaultColor = colors[0];

            for (int i = 0; i < states.length; i++) {
                if (states[i].length == 0) {
                    mDefaultColor = colors[i];
                }
            }
        }
    
Methods Summary
public static android.content.res.ColorStateListaddFirstIfMissing(android.content.res.ColorStateList colorStateList, int state, int color)
If the color state list does not already have an entry matching the specified state, prepends a state set and color pair to a color state list.

This is a workaround used in TimePicker and DatePicker until we can add support for theme attributes in ColorStateList.

param
colorStateList the source color state list
param
state the state to prepend
param
color the color to use for the given state
return
a new color state list, or the source color state list if there was already a matching state set
hide
Remove when we can support theme attributes.

        final int[][] inputStates = colorStateList.getStates();
        for (int i = 0; i < inputStates.length; i++) {
            final int[] inputState = inputStates[i];
            for (int j = 0; j < inputState.length; j++) {
                if (inputState[j] == state) {
                    return colorStateList;
                }
            }
        }

        final int[][] outputStates = new int[inputStates.length + 1][];
        System.arraycopy(inputStates, 0, outputStates, 1, inputStates.length);
        outputStates[0] = new int[] { state };

        final int[] inputColors = colorStateList.getColors();
        final int[] outputColors = new int[inputColors.length + 1];
        System.arraycopy(inputColors, 0, outputColors, 1, inputColors.length);
        outputColors[0] = color;

        return new ColorStateList(outputStates, outputColors);
    
public static android.content.res.ColorStateListcreateFromXml(Resources r, org.xmlpull.v1.XmlPullParser parser)
Create a ColorStateList from an XML document, given a set of {@link Resources}.

        final AttributeSet attrs = Xml.asAttributeSet(parser);

        int type;
        while ((type=parser.next()) != XmlPullParser.START_TAG
                   && type != XmlPullParser.END_DOCUMENT) {
        }

        if (type != XmlPullParser.START_TAG) {
            throw new XmlPullParserException("No start tag found");
        }

        return createFromXmlInner(r, parser, attrs);
    
private static android.content.res.ColorStateListcreateFromXmlInner(Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs)
Create from inside an XML document. Called on a parser positioned at a tag in an XML document, tries to create a ColorStateList from that tag.

throws
XmlPullParserException if the current tag is not <selector>
return
A color state list for the current tag.

        final ColorStateList colorStateList;
        final String name = parser.getName();
        if (name.equals("selector")) {
            colorStateList = new ColorStateList();
        } else {
            throw new XmlPullParserException(
                    parser.getPositionDescription() + ": invalid drawable tag " + name);
        }

        colorStateList.inflate(r, parser, attrs);
        return colorStateList;
    
public intdescribeContents()

        return 0;
    
public intgetColorForState(int[] stateSet, int defaultColor)
Return the color associated with the given set of {@link android.view.View} states.

param
stateSet an array of {@link android.view.View} states
param
defaultColor the color to return if there's not state spec in this {@link ColorStateList} that matches the stateSet.
return
the color associated with that set of states in this {@link ColorStateList}.

        final int setLength = mStateSpecs.length;
        for (int i = 0; i < setLength; i++) {
            int[] stateSpec = mStateSpecs[i];
            if (StateSet.stateSetMatches(stateSpec, stateSet)) {
                return mColors[i];
            }
        }
        return defaultColor;
    
public int[]getColors()
Return the colors in this {@link ColorStateList}.

return
the colors in this {@link ColorStateList}
hide

        return mColors;
    
public intgetDefaultColor()
Return the default color in this {@link ColorStateList}.

return
the default color in this {@link ColorStateList}.

        return mDefaultColor;
    
public int[][]getStates()
Return the states in this {@link ColorStateList}.

return
the states in this {@link ColorStateList}
hide

        return mStateSpecs;
    
private voidinflate(Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs)
Fill in this object based on the contents of an XML "selector" element.

        int type;

        final int innerDepth = parser.getDepth()+1;
        int depth;

        int[][] stateSpecList = ArrayUtils.newUnpaddedArray(int[].class, 20);
        int[] colorList = new int[stateSpecList.length];
        int listSize = 0;

        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
               && ((depth=parser.getDepth()) >= innerDepth
                   || type != XmlPullParser.END_TAG)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            if (depth > innerDepth || !parser.getName().equals("item")) {
                continue;
            }

            int alphaRes = 0;
            float alpha = 1.0f;
            int colorRes = 0;
            int color = 0xffff0000;
            boolean haveColor = false;

            int i;
            int j = 0;
            final int numAttrs = attrs.getAttributeCount();
            int[] stateSpec = new int[numAttrs];
            for (i = 0; i < numAttrs; i++) {
                final int stateResId = attrs.getAttributeNameResource(i);
                if (stateResId == 0) break;
                if (stateResId == com.android.internal.R.attr.alpha) {
                    alphaRes = attrs.getAttributeResourceValue(i, 0);
                    if (alphaRes == 0) {
                        alpha = attrs.getAttributeFloatValue(i, 1.0f);
                    }
                } else if (stateResId == com.android.internal.R.attr.color) {
                    colorRes = attrs.getAttributeResourceValue(i, 0);
                    if (colorRes == 0) {
                        color = attrs.getAttributeIntValue(i, color);
                        haveColor = true;
                    }
                } else {
                    stateSpec[j++] = attrs.getAttributeBooleanValue(i, false)
                            ? stateResId : -stateResId;
                }
            }
            stateSpec = StateSet.trimStateSet(stateSpec, j);

            if (colorRes != 0) {
                color = r.getColor(colorRes);
            } else if (!haveColor) {
                throw new XmlPullParserException(
                        parser.getPositionDescription()
                        + ": <item> tag requires a 'android:color' attribute.");
            }

            if (alphaRes != 0) {
                alpha = r.getFloat(alphaRes);
            }

            // Apply alpha modulation.
            final int alphaMod = MathUtils.constrain((int) (Color.alpha(color) * alpha), 0, 255);
            color = (color & 0xFFFFFF) | (alphaMod << 24);

            if (listSize == 0 || stateSpec.length == 0) {
                mDefaultColor = color;
            }

            colorList = GrowingArrayUtils.append(colorList, listSize, color);
            stateSpecList = GrowingArrayUtils.append(stateSpecList, listSize, stateSpec);
            listSize++;
        }

        mColors = new int[listSize];
        mStateSpecs = new int[listSize][];
        System.arraycopy(colorList, 0, mColors, 0, listSize);
        System.arraycopy(stateSpecList, 0, mStateSpecs, 0, listSize);
    
public booleanisOpaque()
Indicates whether this color state list is opaque, which means that every color returned from {@link #getColorForState(int[], int)} has an alpha value of 255.

return
True if this color state list is opaque.

        final int n = mColors.length;
        for (int i = 0; i < n; i++) {
            if (Color.alpha(mColors[i]) != 0xFF) {
                return false;
            }
        }
        return true;
    
public booleanisStateful()
Indicates whether this color state list contains more than one state spec and will change color based on state.

return
True if this color state list changes color based on state, false otherwise.
see
#getColorForState(int[], int)

        return mStateSpecs.length > 1;
    
public java.lang.StringtoString()

        return "ColorStateList{" +
               "mStateSpecs=" + Arrays.deepToString(mStateSpecs) +
               "mColors=" + Arrays.toString(mColors) +
               "mDefaultColor=" + mDefaultColor + '}";
    
public static android.content.res.ColorStateListvalueOf(int color)
Creates or retrieves a ColorStateList that always returns a single color.

        // TODO: should we collect these eventually?
        synchronized (sCache) {
            final WeakReference<ColorStateList> ref = sCache.get(color);

            ColorStateList csl = ref != null ? ref.get() : null;
            if (csl != null) {
                return csl;
            }

            csl = new ColorStateList(EMPTY, new int[] { color });
            sCache.put(color, new WeakReference<ColorStateList>(csl));
            return csl;
        }
    
public android.content.res.ColorStateListwithAlpha(int alpha)
Creates a new ColorStateList that has the same states and colors as this one but where each color has the specified alpha value (0-255).

        final int[] colors = new int[mColors.length];
        final int len = colors.length;
        for (int i = 0; i < len; i++) {
            colors[i] = (mColors[i] & 0xFFFFFF) | (alpha << 24);
        }

        return new ColorStateList(mStateSpecs, colors);
    
public voidwriteToParcel(android.os.Parcel dest, int flags)

        final int N = mStateSpecs.length;
        dest.writeInt(N);
        for (int i = 0; i < N; i++) {
            dest.writeIntArray(mStateSpecs[i]);
        }
        dest.writeIntArray(mColors);