1.定義自定義View屬性
在res/values/目錄下建立attrs.xml,内容如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgress">
<!--進度條顔色-->
<attr name="progressColor" format="color"/>
<!--進度條軌道顔色-->
<attr name="orbitColor" format="color"/>
<!--進度顯示文本顔色-->
<attr name="textColor" format="color"/>
<!--進度條軌道寬度-->
<attr name="orbitWidth" format="dimension"/>
<!--進度顯示文本字型大小-->
<attr name="textSize" format="dimension"/>
<!--是否顯示進度文本-->
<attr name="enableText" format="boolean"/>
<attr name="maxProgress" format="integer"/>
<attr name="progress" format="integer"/>
</declare-styleable>
</resources>
2.建立CircleProgress類
public class CircleProgress extends View {
private final static String TAG = "CircleProgress";
private int mHeight;
private int mWidth;
private int mOrbitWidth;
private int mTextSize;
private boolean mEnableText;
private int mColorProgress;
private int mColorOrbit;
private int mColorText;
private int mMaxProgress;
private int mProgress;
private Paint mPaint;
private int mRadius;
public int getOrbitWidth() {
return mOrbitWidth;
}
public void setOrbitWidth(int orbitWidth) {
mOrbitWidth = orbitWidth;
}
public int getTextSize() {
return mTextSize;
}
public void setTextSize(int textSize) {
mTextSize = textSize;
}
public boolean isEnableText() {
return mEnableText;
}
public void setEnableText(boolean enableText) {
mEnableText = enableText;
}
public int getColorProgress() {
return mColorProgress;
}
public void setColorProgress(int colorProgress) {
mColorProgress = colorProgress;
}
public int getColorOrbit() {
return mColorOrbit;
}
public void setColorOrbit(int colorOrbit) {
mColorOrbit = colorOrbit;
}
public int getColorText() {
return mColorText;
}
public void setColorText(int colorText) {
mColorText = colorText;
}
public int getMaxProgress() {
return mMaxProgress;
}
public void setMaxProgress(int maxProgress) {
mMaxProgress = maxProgress;
}
public int getProgress() {
return mProgress;
}
public CircleProgress(Context context) {
this(context,null);
}
public CircleProgress(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleProgress, defStyleAttr, 0);
mOrbitWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgress_orbitWidth, DimenUtil.dp2px(context, 2f));
mTextSize = typedArray.getDimensionPixelSize(R.styleable.CircleProgress_textSize, DimenUtil.sp2px(context, 12f));
mEnableText = typedArray.getBoolean(R.styleable.CircleProgress_enableText, true);
int colorAccent = ContextCompat.getColor(context, R.color.colorAccent);
int defaultOrbitColor = ContextCompat.getColor(context,R.color.cardview_light_background);
mColorProgress = typedArray.getColor(R.styleable.CircleProgress_progressColor, colorAccent);
mColorOrbit = typedArray.getColor(R.styleable.CircleProgress_orbitColor, defaultOrbitColor);
mColorText = typedArray.getColor(R.styleable.CircleProgress_textColor, colorAccent);
mMaxProgress = typedArray.getInt(R.styleable.CircleProgress_maxProgress, 100);
mProgress = typedArray.getInt(R.styleable.CircleProgress_progress, 0);
typedArray.recycle();
mPaint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
if (mWidth>mHeight){
mRadius = mHeight/2-mOrbitWidth;
}else {
mRadius = mWidth/2-mOrbitWidth;
}
int cx = getWidth()/2;
int cy = getHeight()/2;
//畫進度條軌道
mPaint.setColor(mColorOrbit); //設定圓的顔色
mPaint.setStyle(STROKE); //設定空心
mPaint.setStrokeWidth(mOrbitWidth); //設定圓的寬度
mPaint.setAntiAlias(true); //消除鋸齒
canvas.drawCircle(cx, cy, mRadius, mPaint); //畫出圓
//畫進度(圓弧)
mPaint.setColor(mColorProgress); //設定進度的顔色
RectF oval = new RectF(cx-mRadius,cy-mRadius,cx+mRadius,cy+mRadius);
canvas.drawArc(oval, -90, 360 * (mProgress*1f / mMaxProgress), false, mPaint); //根據進度畫圓弧
//畫圓環内百分比文字
if (mEnableText) {
Rect rect = new Rect();
mPaint.setColor(mColorText);
mPaint.setTextSize(mTextSize);
mPaint.setStrokeWidth(0);
String progressText = getProgressText();
mPaint.getTextBounds(progressText, 0, progressText.length(), rect);
Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
int baseline = (mHeight - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
canvas.drawText(progressText, mHeight / 2 - rect.width() / 2, baseline, mPaint);
}
}
public void setProgress(int progress){
mProgress = progress;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mHeight = getMeasuredHeight();
mWidth = getMeasuredWidth();
}
public String getProgressText() {
return (int)(100*(mProgress * 1f / mMaxProgress) )+ "%";
}
}
3.使用方法
<CircleProgress
app:orbitColor="@color/colorGray3"
app:textColor="@color/colorWhite"
app:textSize="13sp"
android:layout_gravity="center_horizontal"
android:layout_width="40dp"
android:layout_height="40dp"/>
最後看一下效果