FileDocCategorySizeDatePackage
ScaleDrawable.javaAPI DocAndroid 5.1 API13827Thu Mar 12 22:22:30 GMT 2015android.graphics.drawable

ScaleDrawable

public class ScaleDrawable extends Drawable implements Drawable.Callback
A Drawable that changes the size of another Drawable based on its current level value. You can control how much the child Drawable changes in width and height based on the level, as well as a gravity to control where it is placed in its overall container. Most often used to implement things like progress bars.

It can be defined in an XML file with the <scale> element. For more information, see the guide to Drawable Resources.

attr
ref android.R.styleable#ScaleDrawable_scaleWidth
attr
ref android.R.styleable#ScaleDrawable_scaleHeight
attr
ref android.R.styleable#ScaleDrawable_scaleGravity
attr
ref android.R.styleable#ScaleDrawable_drawable

Fields Summary
private ScaleState
mState
private boolean
mMutated
private final Rect
mTmpRect
Constructors Summary
ScaleDrawable()


     
        this(null, null);
    
public ScaleDrawable(Drawable drawable, int gravity, float scaleWidth, float scaleHeight)

        this(null, null);

        mState.mDrawable = drawable;
        mState.mGravity = gravity;
        mState.mScaleWidth = scaleWidth;
        mState.mScaleHeight = scaleHeight;

        if (drawable != null) {
            drawable.setCallback(this);
        }
    
private ScaleDrawable(ScaleState state, android.content.res.Resources res)

        mState = new ScaleState(state, this, res);
    
Methods Summary
public voidapplyTheme(android.content.res.Resources.Theme t)

        super.applyTheme(t);

        final ScaleState state = mState;
        if (state == null) {
            return;
        }

        if (state.mThemeAttrs != null) {
            final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.ScaleDrawable);
            try {
                updateStateFromTypedArray(a);
                verifyRequiredAttributes(a);
            } catch (XmlPullParserException e) {
                throw new RuntimeException(e);
            } finally {
                a.recycle();
            }
        }

        if (state.mDrawable != null && state.mDrawable.canApplyTheme()) {
            state.mDrawable.applyTheme(t);
        }
    
public booleancanApplyTheme()

        return (mState != null && mState.canApplyTheme()) || super.canApplyTheme();
    
public voidclearMutated()

hide

        super.clearMutated();
        mState.mDrawable.clearMutated();
        mMutated = false;
    
public voiddraw(Canvas canvas)

        if (mState.mDrawable.getLevel() != 0)
            mState.mDrawable.draw(canvas);
    
public intgetAlpha()

        return mState.mDrawable.getAlpha();
    
public intgetChangingConfigurations()

        return super.getChangingConfigurations()
                | mState.mChangingConfigurations
                | mState.mDrawable.getChangingConfigurations();
    
public ConstantStategetConstantState()

        if (mState.canConstantState()) {
            mState.mChangingConfigurations = getChangingConfigurations();
            return mState;
        }
        return null;
    
public DrawablegetDrawable()
Returns the drawable scaled by this ScaleDrawable.

        return mState.mDrawable;
    
public intgetIntrinsicHeight()

        return mState.mDrawable.getIntrinsicHeight();
    
public intgetIntrinsicWidth()

        return mState.mDrawable.getIntrinsicWidth();
    
public intgetOpacity()

        return mState.mDrawable.getOpacity();
    
public booleangetPadding(Rect padding)

        // XXX need to adjust padding!
        return mState.mDrawable.getPadding(padding);
    
private static floatgetPercent(android.content.res.TypedArray a, int name, float defaultValue)

        final String s = a.getString(name);
        if (s != null) {
            if (s.endsWith("%")) {
                String f = s.substring(0, s.length() - 1);
                return Float.parseFloat(f) / 100.0f;
            }
        }
        return defaultValue;
    
public voidinflate(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs, android.content.res.Resources.Theme theme)

        super.inflate(r, parser, attrs, theme);

        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.ScaleDrawable);

        // Reset mDrawable to preserve old multiple-inflate behavior. This is
        // silly, but we have CTS tests that rely on it.
        mState.mDrawable = null;

        updateStateFromTypedArray(a);
        inflateChildElements(r, parser, attrs, theme);
        verifyRequiredAttributes(a);
        a.recycle();
    
private voidinflateChildElements(android.content.res.Resources r, org.xmlpull.v1.XmlPullParser parser, android.util.AttributeSet attrs, android.content.res.Resources.Theme theme)

        Drawable dr = null;
        int type;
        final int outerDepth = parser.getDepth();
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }
            dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
        }

        if (dr != null) {
            mState.mDrawable = dr;
            dr.setCallback(this);
        }
    
public voidinvalidateDrawable(Drawable who)

        if (getCallback() != null) {
            getCallback().invalidateDrawable(this);
        }
    
public booleanisStateful()

        return mState.mDrawable.isStateful();
    
public Drawablemutate()

        if (!mMutated && super.mutate() == this) {
            mState.mDrawable.mutate();
            mMutated = true;
        }
        return this;
    
protected voidonBoundsChange(Rect bounds)

        final Rect r = mTmpRect;
        final boolean min = mState.mUseIntrinsicSizeAsMin;
        int level = getLevel();
        int w = bounds.width();
        if (mState.mScaleWidth > 0) {
            final int iw = min ? mState.mDrawable.getIntrinsicWidth() : 0;
            w -= (int) ((w - iw) * (10000 - level) * mState.mScaleWidth / 10000);
        }
        int h = bounds.height();
        if (mState.mScaleHeight > 0) {
            final int ih = min ? mState.mDrawable.getIntrinsicHeight() : 0;
            h -= (int) ((h - ih) * (10000 - level) * mState.mScaleHeight / 10000);
        }
        final int layoutDirection = getLayoutDirection();
        Gravity.apply(mState.mGravity, w, h, bounds, r, layoutDirection);

        if (w > 0 && h > 0) {
            mState.mDrawable.setBounds(r.left, r.top, r.right, r.bottom);
        }
    
protected booleanonLevelChange(int level)

        mState.mDrawable.setLevel(level);
        onBoundsChange(getBounds());
        invalidateSelf();
        return true;
    
protected booleanonStateChange(int[] state)

        boolean changed = mState.mDrawable.setState(state);
        onBoundsChange(getBounds());
        return changed;
    
public voidscheduleDrawable(Drawable who, java.lang.Runnable what, long when)

        if (getCallback() != null) {
            getCallback().scheduleDrawable(this, what, when);
        }
    
public voidsetAlpha(int alpha)

        mState.mDrawable.setAlpha(alpha);
    
public voidsetColorFilter(ColorFilter cf)

        mState.mDrawable.setColorFilter(cf);
    
public voidsetTintList(android.content.res.ColorStateList tint)

        mState.mDrawable.setTintList(tint);
    
public voidsetTintMode(android.graphics.PorterDuff.Mode tintMode)

        mState.mDrawable.setTintMode(tintMode);
    
public booleansetVisible(boolean visible, boolean restart)

        mState.mDrawable.setVisible(visible, restart);
        return super.setVisible(visible, restart);
    
public voidunscheduleDrawable(Drawable who, java.lang.Runnable what)

        if (getCallback() != null) {
            getCallback().unscheduleDrawable(this, what);
        }
    
private voidupdateStateFromTypedArray(android.content.res.TypedArray a)

        final ScaleState state = mState;

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

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

        state.mScaleWidth = getPercent(
                a, R.styleable.ScaleDrawable_scaleWidth, state.mScaleWidth);
        state.mScaleHeight = getPercent(
                a, R.styleable.ScaleDrawable_scaleHeight, state.mScaleHeight);
        state.mGravity = a.getInt(R.styleable.ScaleDrawable_scaleGravity, state.mGravity);
        state.mUseIntrinsicSizeAsMin = a.getBoolean(
                R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, state.mUseIntrinsicSizeAsMin);

        final Drawable dr = a.getDrawable(R.styleable.ScaleDrawable_drawable);
        if (dr != null) {
            state.mDrawable = dr;
            dr.setCallback(this);
        }
    
private voidverifyRequiredAttributes(android.content.res.TypedArray a)

        // If we're not waiting on a theme, verify required attributes.
        if (mState.mDrawable == null && (mState.mThemeAttrs == null
                || mState.mThemeAttrs[R.styleable.ScaleDrawable_drawable] == 0)) {
            throw new XmlPullParserException(a.getPositionDescription()
                    + ": <scale> tag requires a 'drawable' attribute or "
                    + "child tag defining a drawable");
        }