FileDocCategorySizeDatePackage
MaterialProgressDrawable.javaAPI DocAndroid 5.1 API24312Thu Mar 12 22:22:56 GMT 2015android.support.v4.widget

MaterialProgressDrawable

public class MaterialProgressDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable
Fancy progress indicator for Material theme.
hide

Fields Summary
private static final android.view.animation.Interpolator
LINEAR_INTERPOLATOR
private static final android.view.animation.Interpolator
END_CURVE_INTERPOLATOR
private static final android.view.animation.Interpolator
START_CURVE_INTERPOLATOR
private static final android.view.animation.Interpolator
EASE_INTERPOLATOR
static final int
LARGE
static final int
DEFAULT
private static final int
CIRCLE_DIAMETER
private static final float
CENTER_RADIUS
private static final float
STROKE_WIDTH
private static final int
CIRCLE_DIAMETER_LARGE
private static final float
CENTER_RADIUS_LARGE
private static final float
STROKE_WIDTH_LARGE
private final int[]
COLORS
private static final int
ANIMATION_DURATION
The duration of a single progress spin in milliseconds.
private static final float
NUM_POINTS
The number of points in the progress "star".
private final ArrayList
mAnimators
The list of animators operating on this drawable.
private final Ring
mRing
The indicator ring, used to manage animation state.
private float
mRotation
Canvas rotation in degrees.
private static final int
ARROW_WIDTH
Layout info for the arrowhead in dp
private static final int
ARROW_HEIGHT
private static final float
ARROW_OFFSET_ANGLE
private static final int
ARROW_WIDTH_LARGE
Layout info for the arrowhead for the large spinner in dp
private static final int
ARROW_HEIGHT_LARGE
private static final float
MAX_PROGRESS_ARC
private android.content.res.Resources
mResources
private android.view.View
mParent
private android.view.animation.Animation
mAnimation
private float
mRotationCount
private double
mWidth
private double
mHeight
boolean
mFinishing
private final Callback
mCallback
Constructors Summary
public MaterialProgressDrawable(android.content.Context context, android.view.View parent)


         
        mParent = parent;
        mResources = context.getResources();

        mRing = new Ring(mCallback);
        mRing.setColors(COLORS);

        updateSizes(DEFAULT);
        setupAnimators();
    
Methods Summary
private voidapplyFinishTranslation(float interpolatedTime, android.support.v4.widget.MaterialProgressDrawable$Ring ring)

        // shrink back down and complete a full rotation before
        // starting other circles
        // Rotation goes between [0..1].
        float targetRotation = (float) (Math.floor(ring.getStartingRotation() / MAX_PROGRESS_ARC)
                + 1f);
        final float startTrim = ring.getStartingStartTrim()
                + (ring.getStartingEndTrim() - ring.getStartingStartTrim()) * interpolatedTime;
        ring.setStartTrim(startTrim);
        final float rotation = ring.getStartingRotation()
                + ((targetRotation - ring.getStartingRotation()) * interpolatedTime);
        ring.setRotation(rotation);
    
public voiddraw(android.graphics.Canvas c)

        final Rect bounds = getBounds();
        final int saveCount = c.save();
        c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
        mRing.draw(c, bounds);
        c.restoreToCount(saveCount);
    
public intgetAlpha()

        return mRing.getAlpha();
    
public intgetIntrinsicHeight()

        return (int) mHeight;
    
public intgetIntrinsicWidth()

        return (int) mWidth;
    
public intgetOpacity()

        return PixelFormat.TRANSLUCENT;
    
private floatgetRotation()

        return mRotation;
    
public booleanisRunning()

        final ArrayList<Animation> animators = mAnimators;
        final int N = animators.size();
        for (int i = 0; i < N; i++) {
            final Animation animator = animators.get(i);
            if (animator.hasStarted() && !animator.hasEnded()) {
                return true;
            }
        }
        return false;
    
public voidsetAlpha(int alpha)

        mRing.setAlpha(alpha);
    
public voidsetArrowScale(float scale)

param
scale Set the scale of the arrowhead for the spinner.

        mRing.setArrowScale(scale);
    
public voidsetBackgroundColor(int color)
Update the background color of the circle image view.

        mRing.setBackgroundColor(color);
     
public voidsetColorFilter(android.graphics.ColorFilter colorFilter)

        mRing.setColorFilter(colorFilter);
    
public voidsetColorSchemeColors(int colors)
Set the colors used in the progress animation from color resources. The first color will also be the color of the bar that grows in response to a user swipe gesture.

param
colors

        mRing.setColors(colors);
        mRing.setColorIndex(0);
    
public voidsetProgressRotation(float rotation)
Set the amount of rotation to apply to the progress spinner.

param
rotation Rotation is from [0..1]

        mRing.setRotation(rotation);
    
voidsetRotation(float rotation)

        mRotation = rotation;
        invalidateSelf();
    
private voidsetSizeParameters(double progressCircleWidth, double progressCircleHeight, double centerRadius, double strokeWidth, float arrowWidth, float arrowHeight)

        final Ring ring = mRing;
        final DisplayMetrics metrics = mResources.getDisplayMetrics();
        final float screenDensity = metrics.density;

        mWidth = progressCircleWidth * screenDensity;
        mHeight = progressCircleHeight * screenDensity;
        ring.setStrokeWidth((float) strokeWidth * screenDensity);
        ring.setCenterRadius(centerRadius * screenDensity);
        ring.setColorIndex(0);
        ring.setArrowDimensions(arrowWidth * screenDensity, arrowHeight * screenDensity);
        ring.setInsets((int) mWidth, (int) mHeight);
    
public voidsetStartEndTrim(float startAngle, float endAngle)
Set the start and end trim for the progress spinner arc.

param
startAngle start angle
param
endAngle end angle

        mRing.setStartTrim(startAngle);
        mRing.setEndTrim(endAngle);
    
private voidsetupAnimators()

        final Ring ring = mRing;
        final Animation animation = new Animation() {
                @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                if (mFinishing) {
                    applyFinishTranslation(interpolatedTime, ring);
                } else {
                    // The minProgressArc is calculated from 0 to create an
                    // angle that
                    // matches the stroke width.
                    final float minProgressArc = (float) Math.toRadians(
                            ring.getStrokeWidth() / (2 * Math.PI * ring.getCenterRadius()));
                    final float startingEndTrim = ring.getStartingEndTrim();
                    final float startingTrim = ring.getStartingStartTrim();
                    final float startingRotation = ring.getStartingRotation();

                    // Offset the minProgressArc to where the endTrim is
                    // located.
                    final float minArc = MAX_PROGRESS_ARC - minProgressArc;
                    final float endTrim = startingEndTrim + (minArc
                            * START_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime));
                    ring.setEndTrim(endTrim);

                    final float startTrim = startingTrim + (MAX_PROGRESS_ARC
                            * END_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime));
                    ring.setStartTrim(startTrim);

                    final float rotation = startingRotation + (0.25f * interpolatedTime);
                    ring.setRotation(rotation);

                    float groupRotation = ((720.0f / NUM_POINTS) * interpolatedTime)
                            + (720.0f * (mRotationCount / NUM_POINTS));
                    setRotation(groupRotation);
                }
            }
        };
        animation.setRepeatCount(Animation.INFINITE);
        animation.setRepeatMode(Animation.RESTART);
        animation.setInterpolator(LINEAR_INTERPOLATOR);
        animation.setAnimationListener(new Animation.AnimationListener() {

                @Override
            public void onAnimationStart(Animation animation) {
                mRotationCount = 0;
            }

                @Override
            public void onAnimationEnd(Animation animation) {
                // do nothing
            }

                @Override
            public void onAnimationRepeat(Animation animation) {
                ring.storeOriginals();
                ring.goToNextColor();
                ring.setStartTrim(ring.getEndTrim());
                if (mFinishing) {
                    // finished closing the last ring from the swipe gesture; go
                    // into progress mode
                    mFinishing = false;
                    animation.setDuration(ANIMATION_DURATION);
                    ring.setShowArrow(false);
                } else {
                    mRotationCount = (mRotationCount + 1) % (NUM_POINTS);
                }
            }
        });
        mAnimation = animation;
    
public voidshowArrow(boolean show)

param
show Set to true to display the arrowhead on the progress spinner.

        mRing.setShowArrow(show);
    
public voidstart()

        mAnimation.reset();
        mRing.storeOriginals();
        // Already showing some part of the ring
        if (mRing.getEndTrim() != mRing.getStartTrim()) {
            mFinishing = true;
            mAnimation.setDuration(ANIMATION_DURATION/2);
            mParent.startAnimation(mAnimation);
        } else {
            mRing.setColorIndex(0);
            mRing.resetOriginals();
            mAnimation.setDuration(ANIMATION_DURATION);
            mParent.startAnimation(mAnimation);
        }
    
public voidstop()

        mParent.clearAnimation();
        setRotation(0);
        mRing.setShowArrow(false);
        mRing.setColorIndex(0);
        mRing.resetOriginals();
    
public voidupdateSizes(int size)
Set the overall size for the progress spinner. This updates the radius and stroke width of the ring.

param
size One of {@link MaterialProgressDrawable.LARGE} or {@link MaterialProgressDrawable.DEFAULT}

        if (size == LARGE) {
            setSizeParameters(CIRCLE_DIAMETER_LARGE, CIRCLE_DIAMETER_LARGE, CENTER_RADIUS_LARGE,
                    STROKE_WIDTH_LARGE, ARROW_WIDTH_LARGE, ARROW_HEIGHT_LARGE);
        } else {
            setSizeParameters(CIRCLE_DIAMETER, CIRCLE_DIAMETER, CENTER_RADIUS, STROKE_WIDTH,
                    ARROW_WIDTH, ARROW_HEIGHT);
        }