FileDocCategorySizeDatePackage
StateListDrawable.javaAPI DocAndroid 5.1 API14720Thu Mar 12 22:22:30 GMT 2015android.graphics.drawable

StateListDrawable

public class StateListDrawable extends DrawableContainer
Lets you assign a number of graphic images to a single Drawable and swap out the visible item by a string ID value.

It can be defined in an XML file with the <selector> element. Each state Drawable is defined in a nested <item> element. For more information, see the guide to Drawable Resources.

attr
ref android.R.styleable#StateListDrawable_visible
attr
ref android.R.styleable#StateListDrawable_variablePadding
attr
ref android.R.styleable#StateListDrawable_constantSize
attr
ref android.R.styleable#DrawableStates_state_focused
attr
ref android.R.styleable#DrawableStates_state_window_focused
attr
ref android.R.styleable#DrawableStates_state_enabled
attr
ref android.R.styleable#DrawableStates_state_checkable
attr
ref android.R.styleable#DrawableStates_state_checked
attr
ref android.R.styleable#DrawableStates_state_selected
attr
ref android.R.styleable#DrawableStates_state_activated
attr
ref android.R.styleable#DrawableStates_state_active
attr
ref android.R.styleable#DrawableStates_state_single
attr
ref android.R.styleable#DrawableStates_state_first
attr
ref android.R.styleable#DrawableStates_state_middle
attr
ref android.R.styleable#DrawableStates_state_last
attr
ref android.R.styleable#DrawableStates_state_pressed

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final boolean
DEFAULT_DITHER
To be proper, we should have a getter for dither (and alpha, etc.) so that proxy classes like this can save/restore their delegates' values, but we don't have getters. Since we do have setters (e.g. setDither), which this proxy forwards on, we have to have some default/initial setting. The initial setting for dither is now true, since it almost always seems to improve the quality at negligible cost.
private StateListState
mStateListState
private boolean
mMutated
Constructors Summary
public StateListDrawable()


      
        this(null, null);
    
private StateListDrawable(StateListState state, android.content.res.Resources res)

        // Every state list drawable has its own constant state.
        final StateListState newState = new StateListState(state, this, res);
        setConstantState(newState);
        onStateChange(getState());
    
StateListDrawable(StateListState state)
This constructor exists so subclasses can avoid calling the default constructor and setting up a StateListDrawable-specific constant state.

        if (state != null) {
            setConstantState(state);
        }
    
Methods Summary
public voidaddState(int[] stateSet, Drawable drawable)
Add a new image/string ID to the set of images.

param
stateSet - An array of resource Ids to associate with the image. Switch to this image by calling setState().
param
drawable -The image to show.

        if (drawable != null) {
            mStateListState.addStateSet(stateSet, drawable);
            // in case the new state matches our current state...
            onStateChange(getState());
        }
    
public voidapplyTheme(android.content.res.Resources.Theme theme)

        super.applyTheme(theme);

        onStateChange(getState());
    
public voidclearMutated()

hide

        super.clearMutated();
        mMutated = false;
    
android.graphics.drawable.StateListDrawable$StateListStatecloneConstantState()

        return new StateListState(mStateListState, this, null);
    
int[]extractStateSet(android.util.AttributeSet attrs)
Extracts state_ attributes from an attribute set.

param
attrs The attribute set.
return
An array of state_ attributes.

        int j = 0;
        final int numAttrs = attrs.getAttributeCount();
        int[] states = new int[numAttrs];
        for (int i = 0; i < numAttrs; i++) {
            final int stateResId = attrs.getAttributeNameResource(i);
            switch (stateResId) {
                case 0:
                    break;
                case R.attr.drawable:
                case R.attr.id:
                    // Ignore attributes from StateListDrawableItem and
                    // AnimatedStateListDrawableItem.
                    continue;
                default:
                    states[j++] = attrs.getAttributeBooleanValue(i, false)
                            ? stateResId : -stateResId;
            }
        }
        states = StateSet.trimStateSet(states, j);
        return states;
    
public intgetStateCount()
Gets the number of states contained in this drawable.

return
The number of states contained in this drawable.
hide
pending API council
see
#getStateSet(int)
see
#getStateDrawable(int)

        return mStateListState.getChildCount();
    
public DrawablegetStateDrawable(int index)
Gets the drawable at an index.

param
index The index of the drawable.
return
The drawable at the index.
hide
pending API council
see
#getStateCount()
see
#getStateSet(int)

        return mStateListState.getChild(index);
    
public intgetStateDrawableIndex(int[] stateSet)
Gets the index of the drawable with the provided state set.

param
stateSet the state set to look up
return
the index of the provided state set, or -1 if not found
hide
pending API council
see
#getStateDrawable(int)
see
#getStateSet(int)

        return mStateListState.indexOfStateSet(stateSet);
    
android.graphics.drawable.StateListDrawable$StateListStategetStateListState()

        return mStateListState;
    
public int[]getStateSet(int index)
Gets the state set at an index.

param
index The index of the state set.
return
The state set at the index.
hide
pending API council
see
#getStateCount()
see
#getStateDrawable(int)

        return mStateListState.mStateSets[index];
    
public voidinflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs, android.content.res.Resources.Theme theme)

        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.StateListDrawable);
        super.inflateWithAttributes(r, parser, a, R.styleable.StateListDrawable_visible);
        updateStateFromTypedArray(a);
        a.recycle();

        inflateChildElements(r, parser, attrs, theme);

        onStateChange(getState());
    
private voidinflateChildElements(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs, android.content.res.Resources.Theme theme)
Inflates child elements from XML.

        final StateListState state = mStateListState;
        final int innerDepth = parser.getDepth() + 1;
        int type;
        int depth;
        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;
            }

            // This allows state list drawable item elements to be themed at
            // inflation time but does NOT make them work for Zygote preload.
            final TypedArray a = obtainAttributes(r, theme, attrs,
                    R.styleable.StateListDrawableItem);
            Drawable dr = a.getDrawable(R.styleable.StateListDrawableItem_drawable);
            a.recycle();

            final int[] states = extractStateSet(attrs);

            // Loading child elements modifies the state of the AttributeSet's
            // underlying parser, so it needs to happen after obtaining
            // attributes and extracting states.
            if (dr == null) {
                while ((type = parser.next()) == XmlPullParser.TEXT) {
                }
                if (type != XmlPullParser.START_TAG) {
                    throw new XmlPullParserException(
                            parser.getPositionDescription()
                                    + ": <item> tag requires a 'drawable' attribute or "
                                    + "child tag defining a drawable");
                }
                dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
            }

            state.addStateSet(states, dr);
        }
    
public booleanisStateful()

        return true;
    
public Drawablemutate()

        if (!mMutated && super.mutate() == this) {
            mStateListState.mutate();
            mMutated = true;
        }
        return this;
    
protected booleanonStateChange(int[] stateSet)

        int idx = mStateListState.indexOfStateSet(stateSet);
        if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "
                + Arrays.toString(stateSet) + " found " + idx);
        if (idx < 0) {
            idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);
        }
        if (selectDrawable(idx)) {
            return true;
        }
        return super.onStateChange(stateSet);
    
protected voidsetConstantState(DrawableContainerState state)

        super.setConstantState(state);

        if (state instanceof StateListState) {
            mStateListState = (StateListState) state;
        }
    
public voidsetLayoutDirection(int layoutDirection)

hide

        super.setLayoutDirection(layoutDirection);

        // Let the container handle setting its own layout direction. Otherwise,
        // we're accessing potentially unused states.
        mStateListState.setLayoutDirection(layoutDirection);
    
private voidupdateStateFromTypedArray(android.content.res.TypedArray a)
Updates the constant state from the values in the typed array.

        final StateListState state = mStateListState;

        // Account for any configuration changes.
        state.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        state.mThemeAttrs = a.extractThemeAttrs();

        state.mVariablePadding = a.getBoolean(
                R.styleable.StateListDrawable_variablePadding, state.mVariablePadding);
        state.mConstantSize = a.getBoolean(
                R.styleable.StateListDrawable_constantSize, state.mConstantSize);
        state.mEnterFadeDuration = a.getInt(
                R.styleable.StateListDrawable_enterFadeDuration, state.mEnterFadeDuration);
        state.mExitFadeDuration = a.getInt(
                R.styleable.StateListDrawable_exitFadeDuration, state.mExitFadeDuration);
        state.mDither = a.getBoolean(
                R.styleable.StateListDrawable_dither, state.mDither);
        state.mAutoMirrored = a.getBoolean(
                R.styleable.StateListDrawable_autoMirrored, state.mAutoMirrored);