Skip to content

Instantly share code, notes, and snippets.

@kamikat
Created July 28, 2014 06:18
Show Gist options
  • Save kamikat/3ac1029ff6ba14ce6c30 to your computer and use it in GitHub Desktop.
Save kamikat/3ac1029ff6ba14ce6c30 to your computer and use it in GitHub Desktop.
Implement circle progress indicator view on android.
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class ProgressCircle extends View {
public static final String TAG = ProgressCircle.class.getSimpleName();
private static final int ALPHA_TRANSPARENT = 0;
private static final int ALPHA_OPAQUE = 255;
private static final boolean DEFAULT_INDETERMINATE_STATE = true;
private static final int DEFAULT_PROGRESS_WIDTH = 5;
private static final int DEFAULT_PROGRESS_BACKGROUND_COLOR = Color.TRANSPARENT;
private static final int DEFAULT_PROGRESS_COLOR = Color.WHITE;
private static final int DEFAULT_INDETERMINATE_PROGRESS_COLOR = Color.WHITE;
private static final int DEFAULT_INDETERMINATE_PROGRESS_PERIOD = 2000;
private static final float DEFAULT_INDETERMINATE_ARC_SIZE = 0.2f;
private boolean mIndeterminate;
private int mProgressWidth;
private int mProgressBackgroundColor;
private int mProgressColor;
private int mIndeterminateProgressColor;
private int mIndeterminatePeriod;
private float mIndeterminateArcSize;
private int mWidth;
private int mHeight;
private RectF mProgressArcRect;
private Paint mPaintProgressBackground;
private Paint mPaintProgress;
private Paint mPaintIndeterminateProgress;
private float mProgress;
private long mLastProgressUpdate;
public ProgressCircle(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ProgressCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.ProgressCircle,
0, 0);
try {
mIndeterminate = a.getBoolean(R.styleable.ProgressCircle_indeterminate, DEFAULT_INDETERMINATE_STATE);
mProgressWidth = a.getDimensionPixelSize(R.styleable.ProgressCircle_progressStrokeWidth, DEFAULT_PROGRESS_WIDTH);
mProgressBackgroundColor = a.getColor(R.styleable.ProgressCircle_progressBackgroundColor, DEFAULT_PROGRESS_BACKGROUND_COLOR);
mProgressColor = a.getColor(R.styleable.ProgressCircle_progressAccentColor, DEFAULT_PROGRESS_COLOR);
mIndeterminateProgressColor = a.getColor(R.styleable.ProgressCircle_indeterminateProgressAccentColor, DEFAULT_INDETERMINATE_PROGRESS_COLOR);
mIndeterminatePeriod = a.getInteger(R.styleable.ProgressCircle_indeterminatePeriod, DEFAULT_INDETERMINATE_PROGRESS_PERIOD);
mIndeterminateArcSize = a.getFloat(R.styleable.ProgressCircle_indeterminateArcSize, DEFAULT_INDETERMINATE_ARC_SIZE);
} finally {
a.recycle();
}
mPaintProgressBackground = new Paint() {{
this.setColor(mProgressBackgroundColor);
this.setStrokeWidth(mProgressWidth);
this.setStyle(Style.STROKE);
}};
mPaintProgress = new Paint() {{
this.setColor(mProgressColor);
this.setStrokeWidth(mProgressWidth);
this.setStyle(Style.STROKE);
}};
mPaintIndeterminateProgress = new Paint() {{
this.setColor(mIndeterminateProgressColor);
this.setStrokeWidth(mProgressWidth);
this.setStyle(Style.STROKE);
}};
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
mProgressArcRect = new RectF(mProgressWidth, mProgressWidth, mWidth - mProgressWidth, mHeight - mProgressWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
long now = System.currentTimeMillis();
// draw background circle
drawCircle(canvas, mPaintProgressBackground);
if (mIndeterminate) {
long duration = now - mLastProgressUpdate;
if (duration > mIndeterminatePeriod) {
mLastProgressUpdate = now;
duration = 0;
}
drawCircle(canvas, (float) duration / mIndeterminatePeriod, mIndeterminateArcSize, mPaintIndeterminateProgress);
invalidate(); // animation loop
} else {
drawCircle(canvas, 0.0f, mProgress, mPaintProgress);
}
}
protected void drawCircle(Canvas canvas, Paint paint) {
drawCircle(canvas, 0.0f, 1.0f, paint);
}
protected void drawCircle(Canvas canvas, float start, float size, Paint paint) {
canvas.drawArc(mProgressArcRect, -90.0f + 360.0f * start, 360.0f * size, false, paint);
}
public void setIndeterminate(boolean yes) {
if (mIndeterminate != yes) {
mIndeterminate = yes;
invalidate();
}
}
public void setProgress(float progress) {
mProgress = progress;
invalidate();
}
}
<declare-styleable name="ProgressCircle">
<attr name="indeterminate" format="boolean" />
<attr name="progressStrokeWidth" format="dimension" />
<attr name="progressBackgroundColor" format="color" />
<attr name="progressAccentColor" format="color" />
<attr name="indeterminateProgressAccentColor" format="color" />
<attr name="indeterminatePeriod" format="integer" />
<attr name="indeterminateArcSize" format="float" />
</declare-styleable>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment