Created
April 17, 2016 14:16
-
-
Save rafakob/b2eceb43c6286a9381a3c5cb18eaacde to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<declare-styleable name="CircleProgressBar"> | |
<attr name="cpb_min" format="integer"/> | |
<attr name="cpb_max" format="integer"/> | |
<attr name="cpb_progress" format="integer"/> | |
<attr name="cpb_startAngle" format="integer"/> | |
<attr name="cpb_color" format="color"/> | |
<attr name="cpb_colorBack" format="color"/> | |
<attr name="cpb_backAlpha" format="float"/> | |
<attr name="cpb_stroke" format="dimension"/> | |
<attr name="cpb_strokeFinal" format="dimension"/> | |
<attr name="cpb_animDuration" format="integer"/> | |
</declare-styleable> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GIF: http://i.giphy.com/26AHH8u6ailoD3hpm.gif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CircleProgressBar extends View { | |
/* Attributes */ | |
private int mMin = 0; | |
private int mMax = 100; | |
private float mProgress = 0; | |
private float mStroke = 5; | |
private float mStrokeFinal; | |
private int mColor = Color.DKGRAY; | |
private int mColorBack; | |
private float mBackAlpha = 0.3f; | |
private int mStartAngle = -90; | |
private int mAnimDuration = 1000; | |
/* Internal */ | |
private Paint mForegroundPaint; | |
private Paint mBackgroundPaint; | |
private RectF mRectF; | |
private boolean mIsStrokeExpanded; | |
public CircleProgressBar(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(context, attrs); | |
} | |
private void init(Context context, AttributeSet attrs) { | |
mRectF = new RectF(); | |
mIsStrokeExpanded = false; | |
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleProgressBar, 0, 0); | |
try { | |
mMin = typedArray.getInt(R.styleable.CircleProgressBar_cpb_min, mMin); | |
mMax = typedArray.getInt(R.styleable.CircleProgressBar_cpb_max, mMax); | |
mProgress = typedArray.getFloat(R.styleable.CircleProgressBar_cpb_progress, mProgress); | |
mStroke = typedArray.getDimension(R.styleable.CircleProgressBar_cpb_stroke, mStroke); | |
mStrokeFinal = typedArray.getDimension(R.styleable.CircleProgressBar_cpb_strokeFinal, mStroke); | |
mColor = typedArray.getInt(R.styleable.CircleProgressBar_cpb_color, mColor); | |
mColorBack = typedArray.getInt(R.styleable.CircleProgressBar_cpb_colorBack, mColor); | |
mBackAlpha = typedArray.getFloat(R.styleable.CircleProgressBar_cpb_backAlpha, mBackAlpha); | |
mStartAngle = typedArray.getInt(R.styleable.CircleProgressBar_cpb_startAngle, mStartAngle); | |
mAnimDuration = typedArray.getInt(R.styleable.CircleProgressBar_cpb_animDuration, mAnimDuration); | |
} finally { | |
typedArray.recycle(); | |
} | |
mColorBack = ColorUtils.adjustAlpha(mColorBack, mBackAlpha); | |
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
mBackgroundPaint.setColor(mColorBack); | |
mBackgroundPaint.setStyle(Paint.Style.STROKE); | |
mBackgroundPaint.setStrokeWidth(mStroke); | |
mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
mForegroundPaint.setColor(mColor); | |
mForegroundPaint.setStyle(Paint.Style.STROKE); | |
mForegroundPaint.setStrokeWidth(mStroke); | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
final int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); | |
final int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); | |
final int min = Math.min(width, height); | |
setMeasuredDimension(min, min); | |
mRectF.set(0 + mStrokeFinal / 2, 0 + mStrokeFinal / 2, min - mStrokeFinal / 2, min - mStrokeFinal / 2); | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
super.onDraw(canvas); | |
float angle = 360 * mProgress / mMax; | |
canvas.drawOval(mRectF, mBackgroundPaint); | |
canvas.drawArc(mRectF, mStartAngle, angle, false, mForegroundPaint); | |
} | |
public void setStroke(float stroke) { | |
mStroke = stroke; | |
mForegroundPaint.setStrokeWidth(stroke); | |
invalidate(); | |
} | |
public void setProgress(float progress) { | |
mProgress = progress; | |
invalidate(); | |
} | |
public void setAnimDuration(int animDuration) { | |
mAnimDuration = animDuration; | |
} | |
public Animator setProgressWithAnimation(float progress) { | |
AnimatorSet animatorSet = new AnimatorSet(); | |
ObjectAnimator progressAnimator = ObjectAnimator.ofFloat(this, "progress", mProgress, progress); | |
progressAnimator.setDuration(mAnimDuration); | |
progressAnimator.setInterpolator(new AccelerateInterpolator()); | |
if (mProgress == 0) { | |
mIsStrokeExpanded = false; | |
} | |
if (mStroke == mStrokeFinal || mIsStrokeExpanded) { | |
progressAnimator.start(); | |
return progressAnimator; | |
} | |
ValueAnimator strokeAnimator = ValueAnimator.ofFloat(mStroke, mStrokeFinal); | |
strokeAnimator.setDuration(mAnimDuration); | |
strokeAnimator.setInterpolator(new CircInInterpolator()); | |
strokeAnimator.addUpdateListener(valueAnimator1 -> { | |
mForegroundPaint.setStrokeWidth((float) valueAnimator1.getAnimatedValue()); | |
invalidate(); | |
}); | |
animatorSet.playTogether(progressAnimator, strokeAnimator); | |
animatorSet.start(); | |
mIsStrokeExpanded = true; | |
return animatorSet; | |
} | |
public static class CircInInterpolator implements TimeInterpolator { | |
@Override | |
public float getInterpolation(float elapsedTimeRate) { | |
return (float) -(Math.sqrt(1f - elapsedTimeRate * elapsedTimeRate) - 1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment