Android Open Source - Material Circular Progress Drawable






From Project

Back to project page Material.

License

The source code is released under:

Apache License

If you think the Android project Material listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.rey.material.drawable;
/*from w ww  . j a va2 s  .c  o  m*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import com.rey.material.R;
import com.rey.material.util.ColorUtil;
import com.rey.material.util.ThemeUtil;
import com.rey.material.util.ViewUtil;
import com.rey.material.view.ProgressView;

public class CircularProgressDrawable extends Drawable implements Animatable {
  
  private long mLastUpdateTime;
  private long mLastProgressStateTime;
  private long mLastRunStateTime;
      
  private int mProgressState;
  
  private static final int PROGRESS_STATE_HIDE = -1;
  private static final int PROGRESS_STATE_STRETCH = 0;
  private static final int PROGRESS_STATE_KEEP_STRETCH = 1;
  private static final int PROGRESS_STATE_SHRINK = 2;
  private static final int PROGRESS_STATE_KEEP_SHRINK = 3;
  
  private int mRunState = RUN_STATE_STOPPED;
  
  private static final int RUN_STATE_STOPPED = 0;
  private static final int RUN_STATE_STARTING = 1;
  private static final int RUN_STATE_STARTED = 2;
  private static final int RUN_STATE_RUNNING = 3;
  private static final int RUN_STATE_STOPPING = 4;
  
  private Paint mPaint;
  private RectF mRect;
  private float mStartAngle;
  private float mSweepAngle;
  private int mStrokeColorIndex;
  
  private int mPadding;  
  private float mInitialAngle;  
  private float mProgressPercent;
  private float mSecondaryProgressPercent;
  private float mMaxSweepAngle;  
  private float mMinSweepAngle;  
  private int mStrokeSize;
  private int[] mStrokeColors;
  private int mStrokeSecondaryColor;  
  private boolean mReverse;
  private int mRotateDuration;
  private int mTransformDuration;
  private int mKeepDuration;  
  private float mInStepPercent;
  private int[] mInColors;
  private int mInAnimationDuration;
  private int mOutAnimationDuration;
  private int mProgressMode;
  private Interpolator mTransformInterpolator; 
    
  private CircularProgressDrawable(int padding, float initialAngle, float progressPercent, float secondaryProgressPercent, float maxSweepAngle, float minSweepAngle, int strokeSize, int[] strokeColors, int strokeSecondaryColor, boolean reverse, int rotateDuration, int transformDuration, int keepDuration, Interpolator transformInterpolator, int progressMode, int inAnimDuration, float inStepPercent, int[] inStepColors, int outAnimDuration){
    mPadding = padding;
    mInitialAngle = initialAngle;
    setProgress(progressPercent);
    setSecondaryProgress(secondaryProgressPercent);
    mMaxSweepAngle = maxSweepAngle;
    mMinSweepAngle = minSweepAngle;
    mStrokeSize = strokeSize;
    mStrokeColors = strokeColors;
    mStrokeSecondaryColor = strokeSecondaryColor;
    mReverse = reverse;
    mRotateDuration = rotateDuration;
    mTransformDuration = transformDuration;
    mKeepDuration = keepDuration;
    mTransformInterpolator = transformInterpolator;
    mProgressMode = progressMode;
    mInAnimationDuration = inAnimDuration;
    mInStepPercent = inStepPercent;
    mInColors = inStepColors;
    mOutAnimationDuration = outAnimDuration;
    
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeJoin(Paint.Join.ROUND);    
    
    mRect = new RectF();
  }
    
  @Override
  public void draw(Canvas canvas) {      
    switch (mProgressMode) {
      case ProgressView.MODE_DETERMINATE:
        drawDeterminate(canvas);
        break;
      case ProgressView.MODE_INDETERMINATE:
        drawIndeterminate(canvas);
        break;
    }    
  }
  
  private void drawDeterminate(Canvas canvas){
    Rect bounds = getBounds();    
    float radius = 0f;
    float size = 0f;
    
    if(mRunState == RUN_STATE_STARTING){
      size = (float)mStrokeSize * Math.min(mInAnimationDuration, (SystemClock.uptimeMillis() - mLastRunStateTime)) / mInAnimationDuration;        
      if(size > 0)      
        radius = (Math.min(bounds.width(), bounds.height()) - mPadding * 2 - mStrokeSize * 2 + size) / 2f;  
    }
    else if(mRunState == RUN_STATE_STOPPING){
      size = (float)mStrokeSize * Math.max(0, (mOutAnimationDuration - SystemClock.uptimeMillis() + mLastRunStateTime)) / mOutAnimationDuration;    
      if(size > 0)
        radius = (Math.min(bounds.width(), bounds.height()) - mPadding * 2 - mStrokeSize * 2 + size) / 2f;
    }
    else if(mRunState != RUN_STATE_STOPPED){
      size = mStrokeSize;
      radius = (Math.min(bounds.width(), bounds.height()) - mPadding * 2 - mStrokeSize) / 2f;
    }
    
    if(radius > 0){
      float x = (bounds.left + bounds.right) / 2f;
      float y = (bounds.top + bounds.bottom) / 2f;
      
      mPaint.setStrokeWidth(size);
      mPaint.setStyle(Paint.Style.STROKE);
      
      if(mProgressPercent == 1f){
        mPaint.setColor(mStrokeColors[0]);
        canvas.drawCircle(x, y, radius, mPaint);
      }
      else if(mProgressPercent == 0f){
        mPaint.setColor(mStrokeSecondaryColor);
        canvas.drawCircle(x, y, radius, mPaint);
      }
      else{
        float sweepAngle = (mReverse ? -360 : 360) * mProgressPercent;
        
        mRect.set(x - radius, y - radius, x + radius, y + radius);        
        mPaint.setColor(mStrokeSecondaryColor);      
        canvas.drawArc(mRect, mInitialAngle + sweepAngle, (mReverse ? -360 : 360) - sweepAngle, false, mPaint);
              
        mPaint.setColor(mStrokeColors[0]);
        canvas.drawArc(mRect, mInitialAngle, sweepAngle, false, mPaint);      
      }
    }    
  }
    
  private int getIndeterminateStrokeColor(){
    if(mProgressState != PROGRESS_STATE_KEEP_SHRINK || mStrokeColors.length == 1)
      return mStrokeColors[mStrokeColorIndex];
    
    float value = Math.max(0f, Math.min(1f, (float)(SystemClock.uptimeMillis() - mLastProgressStateTime) / mKeepDuration));
    int prev_index = mStrokeColorIndex == 0 ? mStrokeColors.length - 1 : mStrokeColorIndex - 1;
    
    return ColorUtil.getMiddleColor(mStrokeColors[prev_index], mStrokeColors[mStrokeColorIndex], value);
  }
  
  private void drawIndeterminate(Canvas canvas){
    if(mRunState == RUN_STATE_STARTING){
      Rect bounds = getBounds();        
      float x = (bounds.left + bounds.right) / 2f;
      float y = (bounds.top + bounds.bottom) / 2f;
      float maxRadius = (Math.min(bounds.width(), bounds.height()) - mPadding * 2) / 2f;
      
      float stepTime = 1f / (mInStepPercent * (mInColors.length + 2) + 1);
      float time = (float)(SystemClock.uptimeMillis() - mLastRunStateTime) / mInAnimationDuration;
      float steps =  time / stepTime;
              
      float outerRadius = 0f;
      float innerRadius = 0f; 
      
      for(int i = (int)Math.floor(steps); i >= 0; i--){
        innerRadius = outerRadius;
        outerRadius = Math.min(1f, (steps - i) * mInStepPercent) * maxRadius;
                  
        if(i >= mInColors.length)
          continue;
        
        if(innerRadius == 0){
          mPaint.setColor(mInColors[i]);
          mPaint.setStyle(Paint.Style.FILL);
          canvas.drawCircle(x, y, outerRadius, mPaint);
        }
        else if(outerRadius > innerRadius){
          float radius = (innerRadius + outerRadius) / 2;
          mRect.set(x - radius, y - radius, x + radius, y + radius);  
          
          mPaint.setStrokeWidth(outerRadius - innerRadius);
          mPaint.setStyle(Paint.Style.STROKE);
          mPaint.setColor(mInColors[i]);
          
          canvas.drawCircle(x, y, radius, mPaint);
        }
        else
          break;
      }
      
      if(mProgressState == PROGRESS_STATE_HIDE){
        if(steps >= 1 / mInStepPercent || time >= 1)
          resetAnimation();
      }          
      else{
        float radius = maxRadius - mStrokeSize / 2f;
        
        mRect.set(x - radius, y - radius, x + radius, y + radius);        
        mPaint.setStrokeWidth(mStrokeSize);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(getIndeterminateStrokeColor());
        
        canvas.drawArc(mRect, mStartAngle, mSweepAngle, false, mPaint);
      }
    }
    else if(mRunState == RUN_STATE_STOPPING){
      float size = (float)mStrokeSize * Math.max(0, (mOutAnimationDuration - SystemClock.uptimeMillis() + mLastRunStateTime)) / mOutAnimationDuration;                
      
      if(size > 0){
        Rect bounds = getBounds();
        float radius = (Math.min(bounds.width(), bounds.height()) - mPadding * 2 - mStrokeSize * 2 + size) / 2f;
        float x = (bounds.left + bounds.right) / 2f;
        float y = (bounds.top + bounds.bottom) / 2f;
        
        mRect.set(x - radius, y - radius, x + radius, y + radius);          
        mPaint.setStrokeWidth(size);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(getIndeterminateStrokeColor());
        
        canvas.drawArc(mRect, mStartAngle, mSweepAngle, false, mPaint);
      }
    }
    else if(mRunState != RUN_STATE_STOPPED){
      Rect bounds = getBounds();
      float radius = (Math.min(bounds.width(), bounds.height()) - mPadding * 2 - mStrokeSize) / 2f;
      float x = (bounds.left + bounds.right) / 2f;
      float y = (bounds.top + bounds.bottom) / 2f;
      
      mRect.set(x - radius, y - radius, x + radius, y + radius);        
      mPaint.setStrokeWidth(mStrokeSize);
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setColor(getIndeterminateStrokeColor());
      
      canvas.drawArc(mRect, mStartAngle, mSweepAngle, false, mPaint);
    }    
  }

  @Override
  public void setAlpha(int alpha) {
    mPaint.setAlpha(alpha);
  }

  @Override
  public void setColorFilter(ColorFilter cf) {
    mPaint.setColorFilter(cf);
  }

  @Override
  public int getOpacity() {
    return PixelFormat.TRANSLUCENT;
  }
  
  public int getProgressMode(){
    return mProgressMode;
  }

  public float getProgress(){
    return mProgressPercent;
  }
  
  public float getSecondaryProgress(){
    return mSecondaryProgressPercent;
  }
  
  public void setProgress(float percent){
    percent = Math.min(1f, Math.max(0f, percent));
    if(mProgressPercent != percent){
      mProgressPercent = percent;
      if(isRunning())
        invalidateSelf();
      else if(mProgressPercent != 0f)
        start();
    }
  }
  
  public void setSecondaryProgress(float percent){
    percent = Math.min(1f, Math.max(0f, percent));
    if(mSecondaryProgressPercent != percent){
      mSecondaryProgressPercent = percent;
      if(isRunning())
        invalidateSelf();
      else if(mSecondaryProgressPercent != 0f)
        start();
    }
  }
  
  //Animation: based on http://cyrilmottier.com/2012/11/27/actionbar-on-the-move/
  
  private void resetAnimation(){    
    mLastUpdateTime = SystemClock.uptimeMillis();
    mLastProgressStateTime = mLastUpdateTime;
    mStartAngle = mInitialAngle;
    mStrokeColorIndex = 0;
    mSweepAngle = mReverse ? -mMinSweepAngle : mMinSweepAngle;
    mProgressState = PROGRESS_STATE_STRETCH;
  }
  
  @Override
  public void start() {
    start(mInAnimationDuration > 0);      
  }

  @Override
  public void stop() {
    stop(mOutAnimationDuration > 0);
  }
    
  private void start(boolean withAnimation){
    if(isRunning()) 
      return;
            
    if(withAnimation){
      mRunState = RUN_STATE_STARTING;
      mLastRunStateTime = SystemClock.uptimeMillis();
      mProgressState = PROGRESS_STATE_HIDE;
    }
    else   
        resetAnimation();
    
    scheduleSelf(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION);
      invalidateSelf();  
  }
  
  private void stop(boolean withAnimation){
    if(!isRunning()) 
      return;
    
    if(withAnimation){        
      mLastRunStateTime = SystemClock.uptimeMillis();
      if(mRunState == RUN_STATE_STARTED){
        scheduleSelf(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION);
          invalidateSelf();  
      }
      mRunState = RUN_STATE_STOPPING;  
    }
    else{      
      mRunState = RUN_STATE_STOPPED;
      unscheduleSelf(mUpdater);
      invalidateSelf();
    }    
  }
  
  @Override
  public boolean isRunning() {
    return mRunState != RUN_STATE_STOPPED;
  }
    
  @Override
  public void scheduleSelf(Runnable what, long when) {
    if(mRunState == RUN_STATE_STOPPED)
      mRunState = mInAnimationDuration > 0 ? RUN_STATE_STARTING : RUN_STATE_RUNNING;
      super.scheduleSelf(what, when);
  }
  
  private final Runnable mUpdater = new Runnable() {

      @Override
      public void run() {
        update();
      }
        
  };
    
  private void update(){
    switch (mProgressMode) {
      case ProgressView.MODE_DETERMINATE:
        updateDeterminate();
        break;
      case ProgressView.MODE_INDETERMINATE:
        updateIndeterminate();
        break;
    }
  }
  
  private void updateDeterminate(){
    long curTime = SystemClock.uptimeMillis();
    
    if(mRunState == RUN_STATE_STARTING){
        if(curTime - mLastRunStateTime > mInAnimationDuration){
          mRunState = RUN_STATE_STARTED;
          return;
        }
      }
      else if(mRunState == RUN_STATE_STOPPING){
        if(curTime - mLastRunStateTime > mOutAnimationDuration){
          stop(false);
          return;
        }
      }
    
      if(isRunning())
        scheduleSelf(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION);

      invalidateSelf();
  }
  
  private void updateIndeterminate(){
    //update animation
      long curTime = SystemClock.uptimeMillis();
      float rotateOffset = (curTime - mLastUpdateTime) * 360f / mRotateDuration;        
      if(mReverse)
        rotateOffset = -rotateOffset;        
      mLastUpdateTime = curTime;              

      switch (mProgressState) {
      case PROGRESS_STATE_STRETCH:
        if(mTransformDuration <= 0){
          mSweepAngle = mReverse ? -mMinSweepAngle : mMinSweepAngle;
          mProgressState = PROGRESS_STATE_KEEP_STRETCH;
          mStartAngle += rotateOffset;
          mLastProgressStateTime = curTime;
        }
        else{
          float value = (curTime - mLastProgressStateTime) / (float)mTransformDuration;
          float maxAngle = mReverse ? -mMaxSweepAngle : mMaxSweepAngle;
          float minAngle = mReverse ? -mMinSweepAngle : mMinSweepAngle;
          
          mStartAngle += rotateOffset;
          mSweepAngle = mTransformInterpolator.getInterpolation(value) * (maxAngle - minAngle) + minAngle;
                    
          if(value > 1f){
            mSweepAngle = maxAngle;
              mProgressState = PROGRESS_STATE_KEEP_STRETCH;
              mLastProgressStateTime = curTime;
            }
        }        
        break;
      case PROGRESS_STATE_KEEP_STRETCH:
        mStartAngle += rotateOffset;
        
        if(curTime - mLastProgressStateTime > mKeepDuration){
          mProgressState = PROGRESS_STATE_SHRINK;
          mLastProgressStateTime = curTime;
        }
        break;
      case PROGRESS_STATE_SHRINK:    
        if(mTransformDuration <= 0){
          mSweepAngle = mReverse ? -mMinSweepAngle : mMinSweepAngle;
          mProgressState = PROGRESS_STATE_KEEP_SHRINK;
          mStartAngle += rotateOffset;
          mLastProgressStateTime = curTime;
          mStrokeColorIndex = (mStrokeColorIndex + 1) % mStrokeColors.length;
        }
        else{
          float value = (curTime - mLastProgressStateTime) / (float)mTransformDuration;
          float maxAngle = mReverse ? -mMaxSweepAngle : mMaxSweepAngle;
          float minAngle = mReverse ? -mMinSweepAngle : mMinSweepAngle;
          
          float newSweepAngle = (1f - mTransformInterpolator.getInterpolation(value)) * (maxAngle - minAngle) + minAngle;            
          mStartAngle += rotateOffset + mSweepAngle - newSweepAngle;
          mSweepAngle = newSweepAngle;
          
          if(value > 1f){
            mSweepAngle = minAngle;
              mProgressState = PROGRESS_STATE_KEEP_SHRINK;
              mLastProgressStateTime = curTime;
              mStrokeColorIndex = (mStrokeColorIndex + 1) % mStrokeColors.length;
            }
        }        
        break;
      case PROGRESS_STATE_KEEP_SHRINK:
        mStartAngle += rotateOffset;
        
        if(curTime - mLastProgressStateTime > mKeepDuration){
          mProgressState = PROGRESS_STATE_STRETCH;
          mLastProgressStateTime = curTime;
        }
        break;          
    }
      
      if(mRunState == RUN_STATE_STARTING){
        if(curTime - mLastRunStateTime > mInAnimationDuration){
          mRunState = RUN_STATE_RUNNING;          
          if(mProgressState == PROGRESS_STATE_HIDE)
            resetAnimation();
        }
      }
      else if(mRunState == RUN_STATE_STOPPING){
        if(curTime - mLastRunStateTime > mOutAnimationDuration){
          stop(false);
          return;
        }
      }
      
      if (isRunning())
        scheduleSelf(mUpdater, SystemClock.uptimeMillis() + ViewUtil.FRAME_DURATION);

      invalidateSelf();
  }
  
  public static class Builder{
    private int mPadding;
    private float mInitialAngle;
    private float mProgressPercent;
    private float mSecondaryProgressPercent;
    private float mMaxSweepAngle;
    private float mMinSweepAngle;  
    private int mStrokeSize;
    private int[] mStrokeColors;
    private int mStrokeSecondaryColor;    
    private boolean mReverse;
    private int mRotateDuration;
    private int mTransformDuration;
    private int mKeepDuration;  
    private Interpolator mTransformInterpolator;
    private int mProgressMode;
    private float mInStepPercent;
    private int[] mInColors;
    private int mInAnimationDuration;
    private int mOutAnimationDuration;
    
    public Builder(){}
    
    public Builder(Context context, AttributeSet attrs, int defStyle){
      TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressDrawable, 0, defStyle);  
      int resId;
      
      padding(a.getDimensionPixelSize(R.styleable.CircularProgressDrawable_cpd_padding, 0));
      initialAngle(a.getInteger(R.styleable.CircularProgressDrawable_cpd_initialAngle, 0));
      progressPercent(a.getFloat(R.styleable.CircularProgressDrawable_pv_progress, 0));
      secondaryProgressPercent(a.getFloat(R.styleable.CircularProgressDrawable_pv_secondaryProgress, 0));
      maxSweepAngle(a.getInteger(R.styleable.CircularProgressDrawable_cpd_maxSweepAngle, 270));
      minSweepAngle(a.getInteger(R.styleable.CircularProgressDrawable_cpd_minSweepAngle, 1));
      strokeSize(a.getDimensionPixelSize(R.styleable.CircularProgressDrawable_cpd_strokeSize, ThemeUtil.dpToPx(context, 4)));
      strokeColors(a.getColor(R.styleable.CircularProgressDrawable_cpd_strokeColor, ThemeUtil.colorPrimary(context, 0xFF000000)));
      if((resId = a.getResourceId(R.styleable.CircularProgressDrawable_cpd_strokeColors, 0)) != 0){
        TypedArray ta = context.getResources().obtainTypedArray(resId);                  
        int[] colors = new int[ta.length()];
        for(int j = 0; j < ta.length(); j++)
            colors[j] = ta.getColor(j, 0);                  
        ta.recycle();
        strokeColors(colors);
      }
      strokeSecondaryColor(a.getColor(R.styleable.CircularProgressDrawable_cpd_strokeSecondaryColor, 0));
      reverse(a.getBoolean(R.styleable.CircularProgressDrawable_cpd_reverse, false));
      rotateDuration(a.getInteger(R.styleable.CircularProgressDrawable_cpd_rotateDuration, context.getResources().getInteger(android.R.integer.config_longAnimTime)));
      transformDuration(a.getInteger(R.styleable.CircularProgressDrawable_cpd_transformDuration, context.getResources().getInteger(android.R.integer.config_mediumAnimTime)));
      keepDuration(a.getInteger(R.styleable.CircularProgressDrawable_cpd_keepDuration, context.getResources().getInteger(android.R.integer.config_shortAnimTime)));
      if((resId = a.getResourceId(R.styleable.CircularProgressDrawable_cpd_transformInterpolator, 0)) != 0)
        transformInterpolator(AnimationUtils.loadInterpolator(context, resId));
      progressMode(a.getInteger(R.styleable.CircularProgressDrawable_pv_progressMode, ProgressView.MODE_INDETERMINATE));
      inAnimDuration(a.getInteger(R.styleable.CircularProgressDrawable_cpd_inAnimDuration, context.getResources().getInteger(android.R.integer.config_mediumAnimTime)));
      if((resId = a.getResourceId(R.styleable.CircularProgressDrawable_cpd_inStepColors, 0)) != 0){
        TypedArray ta = context.getResources().obtainTypedArray(resId);                  
        int[] colors = new int[ta.length()];
        for(int j = 0; j < ta.length(); j++)
            colors[j] = ta.getColor(j, 0);                  
        ta.recycle();
        inStepColors(colors);
      }
      inStepPercent(a.getFloat(R.styleable.CircularProgressDrawable_cpd_inStepPercent, 0.5f));
      outAnimDuration(a.getInteger(R.styleable.CircularProgressDrawable_cpd_outAnimDuration, context.getResources().getInteger(android.R.integer.config_mediumAnimTime)));
      a.recycle();
    }
    
    public CircularProgressDrawable build(){
      if(mStrokeColors == null)
        mStrokeColors = new int[]{0xFF0099FF};
      
      if(mInColors == null && mInAnimationDuration > 0)
        mInColors = new int[]{0xFFB5D4FF, 0xFFDEEAFC, 0xFFFAFFFE};
      
      if(mTransformInterpolator == null)
        mTransformInterpolator = new DecelerateInterpolator();
      
      return new CircularProgressDrawable(mPadding, mInitialAngle, mProgressPercent, mSecondaryProgressPercent, mMaxSweepAngle, mMinSweepAngle, mStrokeSize, mStrokeColors, mStrokeSecondaryColor, mReverse, mRotateDuration, mTransformDuration, mKeepDuration, mTransformInterpolator, mProgressMode, mInAnimationDuration, mInStepPercent, mInColors, mOutAnimationDuration);
    }
    
    public Builder padding(int padding){
      mPadding = padding;
      return this;
    }
    
    public Builder initialAngle(float angle){
      mInitialAngle = angle;
      return this;
    }
    
    public Builder progressPercent(float percent){
      mProgressPercent = percent;
      return this;
    }
    
    public Builder secondaryProgressPercent(float percent){
      mSecondaryProgressPercent = percent;
      return this;
    }
    
    public Builder maxSweepAngle(float angle){
      mMaxSweepAngle = angle;
      return this;
    }
    
    public Builder minSweepAngle(float angle){
      mMinSweepAngle = angle;
      return this;
    }
    
    public Builder strokeSize(int strokeSize){
      mStrokeSize = strokeSize;
      return this;
    }
    
    public Builder strokeColors(int... strokeColors){
      mStrokeColors = strokeColors;
      return this;
    }
    
    public Builder strokeSecondaryColor(int color){
      mStrokeSecondaryColor = color;
      return this;
    }
    
    public Builder reverse(boolean reverse){
      mReverse = reverse;
      return this;
    }
    
    public Builder reverse(){
      return reverse(true);
    }
    
    public Builder rotateDuration(int duration){
      mRotateDuration = duration;
      return this;
    }
    
    public Builder transformDuration(int duration){
      mTransformDuration = duration;
      return this;
    }
    
    public Builder keepDuration(int duration){
      mKeepDuration = duration;
      return this;
    }
    
    public Builder transformInterpolator(Interpolator interpolator){
      mTransformInterpolator = interpolator;
      return this;
    }
    
    public Builder progressMode(int mode){
      mProgressMode = mode;
      return this;
    }
        
    public Builder inAnimDuration(int duration){
      mInAnimationDuration = duration;
      return this;
    }
    
    public Builder inStepPercent(float percent){
      mInStepPercent = percent;
      return this;
    }
    
    public Builder inStepColors(int... colors){
      mInColors = colors;
      return this;
    }
    
    public Builder outAnimDuration(int duration){
      mOutAnimationDuration = duration;
      return this;
    }
    
  }
}




Java Source Code List

com.rey.material.ApplicationTest.java
com.rey.material.demo.ButtonFragment.java
com.rey.material.demo.MainActivity.java
com.rey.material.demo.ProgressFragment.java
com.rey.material.demo.SnackbarFragment.java
com.rey.material.demo.SwitchesFragment.java
com.rey.material.demo.TextfieldFragment.java
com.rey.material.drawable.ArrowDrawable.java
com.rey.material.drawable.BlankDrawable.java
com.rey.material.drawable.CheckBoxDrawable.java
com.rey.material.drawable.CircularProgressDrawable.java
com.rey.material.drawable.DividerDrawable.java
com.rey.material.drawable.LineMorphingDrawable.java
com.rey.material.drawable.LinearProgressDrawable.java
com.rey.material.drawable.NavigationDrawerDrawable.java
com.rey.material.drawable.RadioButtonDrawable.java
com.rey.material.drawable.RevealDrawable.java
com.rey.material.drawable.RippleDrawable.java
com.rey.material.drawable.ToolbarRippleDrawable.java
com.rey.material.util.ColorUtil.java
com.rey.material.util.ThemeUtil.java
com.rey.material.util.ViewUtil.java
com.rey.material.view.Button.java
com.rey.material.view.CheckBox.java
com.rey.material.view.CheckedTextView.java
com.rey.material.view.CompoundButton.java
com.rey.material.view.EditText.java
com.rey.material.view.FloatingActionButton.java
com.rey.material.view.ListPopupWindow.java
com.rey.material.view.ListView.java
com.rey.material.view.PopupWindow.java
com.rey.material.view.ProgressView.java
com.rey.material.view.RadioButton.java
com.rey.material.view.RippleManager.java
com.rey.material.view.SnackBar.java
com.rey.material.view.Spinner.java
com.rey.material.view.Switch.java
com.rey.material.view.TabPageIndicator.java
com.rey.material.view.TextView.java