效果:
代码(没有属性,可以自己diy):
package com.example.testk;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* 圆形进度条控件
*
* @author wuyi
* @date 2022/6/7 16:17
*/
public class MyCircleProgress extends View {
private static final String TAG = "MyCircleProgress";
private Paint mPaint;//画笔
private int mWidth;//控件宽度
private int mHeight;//控件高度
private int mArcWidth = 80;//圆弧宽度,刻度长度
private int mBigRadius = 200;//大半径
private int mSmallRadius;//里面小圆的半径
private double angle = 360d;//角度
private double smalAngle;//每个小的刻度角度
private int mCurrent = 60;//标记刻度
private int mMax = 100;//最大刻度数
private RectF mrectF;
private Rect mrect;
public MyCircleProgress(Context context) {
this(context, null);
}
public MyCircleProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyCircleProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setStrokeWidth(3);
mPaint.setColor(Color.GRAY);
mPaint.setAntiAlias(true);
smalAngle = angle / mMax;
mrectF = new RectF();
mrect = new Rect();
}
public void setCurrent(int _current) {
Log.i(TAG, "当前值:" + _current + ",最大值:" + mMax);
this.mCurrent = _current;
invalidate();
}
public void setMax(int _max) {
this.mMax = _max;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
mBigRadius = mWidth / 2;
mSmallRadius = mBigRadius - mArcWidth;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.rotate(-90, mHeight / 2, mHeight / 2);//步骤2
//绘制圆形
//设置为空心圆,如果不理解绘制弧线是什么意思就把这里的属性改为“填充”,跑一下瞬间就明白了
mPaint.setStyle(Paint.Style.STROKE);
//设置圆弧的宽度(圆环的宽度)
mPaint.setStrokeWidth(mArcWidth);
mPaint.setColor(Color.GRAY);
//大圆的半径
float bigCircleRadius = mWidth / 2;
//小圆的半径
float smallCircleRadius = bigCircleRadius - mArcWidth;
//绘制小圆
canvas.drawCircle(bigCircleRadius, bigCircleRadius, smallCircleRadius + mArcWidth / 2, mPaint);
mPaint.setColor(Color.BLUE);
mrectF.set(mArcWidth / 2, mArcWidth / 2, mWidth - mArcWidth / 2, mWidth - mArcWidth / 2);
//绘制圆弧
canvas.drawArc(mrectF, 0, -mCurrent * 360 / mMax, false, mPaint);
//绘制白色的间隙
drawLines(canvas);
canvas.rotate(90, mHeight / 2, mHeight / 2);//旋转画布
//计算百分比
String txt = mCurrent * 100 / mMax + "%";
mPaint.setStrokeWidth(0);
mPaint.setTextSize(40);
mPaint.getTextBounds(txt, 0, txt.length(), mrect);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
//绘制百分比
canvas.drawText(txt, bigCircleRadius - mrect.width() / 2, bigCircleRadius + mrect.height() / 2, mPaint);
}
/**
* 画出刻度
*
* @param canvas
*/
private void drawLines(Canvas canvas) {
mPaint.setStrokeWidth(6);
int centerWidth = mWidth / 2;
int centerheight = mHeight / 2;
for (int i = 0; i < mMax; i++) {
float cosAngle = (float) Math.cos(Math.toRadians(smalAngle * i));
float sinAngle = (float) Math.sin(Math.toRadians(smalAngle * i));
Log.d("WY", mCurrent + "--" + i);
if (mCurrent == i || i == 0) {
Log.d("WY", "line---");
mPaint.setColor(Color.WHITE);
canvas.drawLine(centerWidth + mSmallRadius * cosAngle, centerheight - mSmallRadius * sinAngle, centerWidth + mBigRadius * cosAngle, centerheight - mBigRadius * sinAngle, mPaint);
} else {
// mPaint.setColor(Color.GREEN);
}
}
}
}