FileDocCategorySizeDatePackage
RotateDrawable.javaAPI DocAndroid 5.1 API19003Thu Mar 12 22:22:30 GMT 2015android.graphics.drawable

RotateDrawable

public class RotateDrawable extends Drawable implements Drawable.Callback

A Drawable that can rotate another Drawable based on the current level value. The start and end angles of rotation can be controlled to map any circular arc to the level values range.

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

attr
ref android.R.styleable#RotateDrawable_visible
attr
ref android.R.styleable#RotateDrawable_fromDegrees
attr
ref android.R.styleable#RotateDrawable_toDegrees
attr
ref android.R.styleable#RotateDrawable_pivotX
attr
ref android.R.styleable#RotateDrawable_pivotY
attr
ref android.R.styleable#RotateDrawable_drawable

Fields Summary
private static final float
MAX_LEVEL
private final RotateState
mState
private boolean
mMutated
Constructors Summary
public RotateDrawable()
Create a new rotating drawable with an empty state.


                  
      
        this(null, null);
    
private RotateDrawable(RotateState rotateState, android.content.res.Resources res)
Create a new rotating drawable with the specified state. A copy of this state is used as the internal state for the newly created drawable.

param
rotateState the state for this drawable

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

        super.applyTheme(t);

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

        if (state.mThemeAttrs != null) {
            final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.RotateDrawable);
            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(android.graphics.Canvas canvas)

        final RotateState st = mState;
        final Drawable d = st.mDrawable;
        final Rect bounds = d.getBounds();
        final int w = bounds.right - bounds.left;
        final int h = bounds.bottom - bounds.top;
        final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
        final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;

        final int saveCount = canvas.save();
        canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
        d.draw(canvas);
        canvas.restoreToCount(saveCount);
    
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()

return
The drawable rotated by this RotateDrawable

        return mState.mDrawable;
    
public floatgetFromDegrees()

return
The starting angle for rotation in degrees
see
#setFromDegrees(float)
attr
ref android.R.styleable#RotateDrawable_fromDegrees

        return mState.mFromDegrees;
    
public intgetIntrinsicHeight()

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

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

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

        return mState.mDrawable.getPadding(padding);
    
public floatgetPivotX()

return
X position around which to rotate
see
#setPivotX(float)
attr
ref android.R.styleable#RotateDrawable_pivotX

        return mState.mPivotX;
    
public floatgetPivotY()

return
Y position around which to rotate
see
#setPivotY(float)
attr
ref android.R.styleable#RotateDrawable_pivotY

        return mState.mPivotY;
    
public floatgetToDegrees()

return
The ending angle for rotation in degrees
see
#setToDegrees(float)
attr
ref android.R.styleable#RotateDrawable_toDegrees

        return mState.mToDegrees;
    
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.RotateDrawable);
        super.inflateWithAttributes(r, parser, a, R.styleable.RotateDrawable_visible);

        // 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)

        final Callback callback = getCallback();
        if (callback != null) {
            callback.invalidateDrawable(this);
        }
    
public booleanisPivotXRelative()

return
True if the X pivot represents a fraction of the drawable width, or false if it represents an absolute value in pixels
see
#setPivotXRelative(boolean)

        return mState.mPivotXRel;
    
public booleanisPivotYRelative()

return
True if the Y pivot represents a fraction of the drawable height, or false if it represents an absolute value in pixels
see
#setPivotYRelative(boolean)

        return mState.mPivotYRel;
    
public booleanisStateful()

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

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

        mState.mDrawable.setBounds(bounds.left, bounds.top,
                bounds.right, bounds.bottom);
    
protected booleanonLevelChange(int level)

        mState.mDrawable.setLevel(level);
        onBoundsChange(getBounds());

        mState.mCurrentDegrees = mState.mFromDegrees +
                (mState.mToDegrees - mState.mFromDegrees) *
                        (level / MAX_LEVEL);

        invalidateSelf();
        return true;
    
protected booleanonStateChange(int[] state)

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

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

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

        mState.mDrawable.setColorFilter(cf);
    
public voidsetDrawable(Drawable drawable)
Sets the drawable rotated by this RotateDrawable.

param
drawable The drawable to rotate

        final Drawable oldDrawable = mState.mDrawable;
        if (oldDrawable != drawable) {
            if (oldDrawable != null) {
                oldDrawable.setCallback(null);
            }
            mState.mDrawable = drawable;
            if (drawable != null) {
                drawable.setCallback(this);
            }
        }
    
public voidsetFromDegrees(float fromDegrees)
Sets the start angle for rotation.

param
fromDegrees Starting angle in degrees
see
#getFromDegrees()
attr
ref android.R.styleable#RotateDrawable_fromDegrees

        if (mState.mFromDegrees != fromDegrees) {
            mState.mFromDegrees = fromDegrees;
            invalidateSelf();
        }
    
public voidsetPivotX(float pivotX)
Sets the X position around which the drawable is rotated.

param
pivotX X position around which to rotate. If the X pivot is relative, the position represents a fraction of the drawable width. Otherwise, the position represents an absolute value in pixels.
see
#setPivotXRelative(boolean)
attr
ref android.R.styleable#RotateDrawable_pivotX

        if (mState.mPivotX != pivotX) {
            mState.mPivotX = pivotX;
            invalidateSelf();
        }
    
public voidsetPivotXRelative(boolean relative)
Sets whether the X pivot value represents a fraction of the drawable width or an absolute value in pixels.

param
relative True if the X pivot represents a fraction of the drawable width, or false if it represents an absolute value in pixels
see
#isPivotXRelative()

        if (mState.mPivotXRel != relative) {
            mState.mPivotXRel = relative;
            invalidateSelf();
        }
    
public voidsetPivotY(float pivotY)
Sets the Y position around which the drawable is rotated.

param
pivotY Y position around which to rotate. If the Y pivot is relative, the position represents a fraction of the drawable height. Otherwise, the position represents an absolute value in pixels.
see
#getPivotY()
attr
ref android.R.styleable#RotateDrawable_pivotY

        if (mState.mPivotY != pivotY) {
            mState.mPivotY = pivotY;
            invalidateSelf();
        }
    
public voidsetPivotYRelative(boolean relative)
Sets whether the Y pivot value represents a fraction of the drawable height or an absolute value in pixels.

param
relative True if the Y pivot represents a fraction of the drawable height, or false if it represents an absolute value in pixels
see
#isPivotYRelative()

        if (mState.mPivotYRel != relative) {
            mState.mPivotYRel = relative;
            invalidateSelf();
        }
    
public voidsetTintList(android.content.res.ColorStateList tint)

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

        mState.mDrawable.setTintMode(tintMode);
    
public voidsetToDegrees(float toDegrees)
Sets the end angle for rotation.

param
toDegrees Ending angle in degrees
see
#getToDegrees()
attr
ref android.R.styleable#RotateDrawable_toDegrees

        if (mState.mToDegrees != toDegrees) {
            mState.mToDegrees = toDegrees;
            invalidateSelf();
        }
    
public booleansetVisible(boolean visible, boolean restart)

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

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

        final RotateState state = mState;

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

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

        if (a.hasValue(R.styleable.RotateDrawable_pivotX)) {
            final TypedValue tv = a.peekValue(R.styleable.RotateDrawable_pivotX);
            state.mPivotXRel = tv.type == TypedValue.TYPE_FRACTION;
            state.mPivotX = state.mPivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
        }

        if (a.hasValue(R.styleable.RotateDrawable_pivotY)) {
            final TypedValue tv = a.peekValue(R.styleable.RotateDrawable_pivotY);
            state.mPivotYRel = tv.type == TypedValue.TYPE_FRACTION;
            state.mPivotY = state.mPivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
        }

        state.mFromDegrees = a.getFloat(R.styleable.RotateDrawable_fromDegrees, state.mFromDegrees);
        state.mToDegrees = a.getFloat(R.styleable.RotateDrawable_toDegrees, state.mToDegrees);
        state.mCurrentDegrees = state.mFromDegrees;

        final Drawable dr = a.getDrawable(R.styleable.RotateDrawable_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()
                    + ": <rotate> tag requires a 'drawable' attribute or "
                    + "child tag defining a drawable");
        }