Created
July 28, 2014 06:18
-
-
Save kamikat/3ac1029ff6ba14ce6c30 to your computer and use it in GitHub Desktop.
Implement circle progress indicator view on android.
This file contains hidden or 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
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(); | |
} | |
} |
This file contains hidden or 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="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