Skip to content

Instantly share code, notes, and snippets.

@rishabhmhjn
Created December 19, 2014 17:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rishabhmhjn/05f1c11a9e0895260a35 to your computer and use it in GitHub Desktop.
Save rishabhmhjn/05f1c11a9e0895260a35 to your computer and use it in GitHub Desktop.
Creating Arc shaped progress bars (http://i.imgur.com/WNFX38Z.png)
package me.rishabhmhjn.droid.widgets;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.ProgressBar;
import me.rishabhmhjn.droid.R;
public class ArcProgressBar extends ProgressBar {
private RectF mRect;
private RectF mProgressRect;
private RectF mEmptyRect;
private Bitmap mTransparentBm;
private Paint mPaint;
private Paint mBackgroundPaint;
private Paint mTransparentPaint;
private Canvas mTempCanvas;
private float mBorderWidth = 20;
private int mProgressColor = 0xFFFF0000;
private int mBackgroundColor = 0xFFFF00FF;
private int mDrawDirection = 0;
private int mStartAngle = -90;
public ArcProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
final TypedArray a = getContext()
.obtainStyledAttributes(attrs, R.styleable.ArcProgressBar, defStyle, 0);
mBorderWidth = a.getDimension(R.styleable.ArcProgressBar_borderWidth, mBorderWidth);
mBackgroundColor = a.getColor(R.styleable.ArcProgressBar_backgroundColor, mBackgroundColor);
mProgressColor = a.getColor(R.styleable.ArcProgressBar_progressColor, mProgressColor);
mDrawDirection = a.getInteger(R.styleable.ArcProgressBar_drawDirection, mDrawDirection);
mStartAngle = a.getInteger(R.styleable.ArcProgressBar_startAngle, mStartAngle);
a.recycle();
mRect = new RectF();
mProgressRect = new RectF();
mEmptyRect = new RectF();
mPaint = new Paint();
mPaint.setColor(mProgressColor);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(mBorderWidth);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
mBackgroundPaint = new Paint(mPaint);
mBackgroundPaint.setColor(mBackgroundColor);
mTransparentPaint = new Paint();
mTransparentPaint.setColor(getResources().getColor(android.R.color.transparent));
mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mTransparentPaint.setAntiAlias(true);
}
@Override
protected synchronized void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
mTempCanvas.drawArc(mRect, 0, 360, true, mBackgroundPaint);
if (getProgress() > 0) {
float angle = 360 * (float) getProgress() / getMax();
angle = mDrawDirection == 0 ? -angle : angle;
mTempCanvas.drawArc(mProgressRect, mStartAngle, angle, true, mPaint);
}
mTempCanvas.drawOval(mEmptyRect, mTransparentPaint);
canvas.drawBitmap(mTransparentBm, 0, 0, null);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
float offset = mBorderWidth / 2;
mRect.set(offset, offset, w - offset, h - offset);
mProgressRect.set(offset, offset, w - offset, h - offset);
mEmptyRect.set(mBorderWidth, mBorderWidth, w - mBorderWidth, h - mBorderWidth);
mTransparentBm = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mTransparentBm.eraseColor(Color.TRANSPARENT);
mTempCanvas = new Canvas(mTransparentBm);
}
}
<resources>
<declare-styleable name="ArcProgressBar">
<attr name="borderWidth" format="dimension"/>
<attr name="backgroundColor" format="color"/>
<attr name="progressColor" format="color"/>
<attr name="startAngle" format="integer"/>
<attr name="drawDirection" format="enum">
<enum name="anti_clockwise" value="0"/>
<enum name="clockwise" value="1"/>
</attr>
</declare-styleable>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<me.rishabhmhjn.droid.widgets.ArcProgressBar
android:layout_height="300dp"
android:layout_width="300dp"
android:max="360"
android:progress="20"
app:borderWidth="10dp"/>
</LinearLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment