一、效果图
![](https://img.haomeiwen.com/i8703441/fb16459ccd542f5b.png)
圆形进度条.png
二、自定义思路步骤分析
- 确定控件的大小,宽高相等
setMeasuredDimension(mViewSize,mViewSize);
- 画背景圆环
float radius = mViewSize/2 - ringWidth/2;
canvas.drawCircle(mViewSize/2,mViewSize/2,radius,mBackgroundPaint);
- 画当前进度圆弧
canvas.drawArc
- 将坐标原点移到控件中心
canvas.translate(getWidth()/2,getHeight()/2);
- 绘制进度数字
canvas.drawText
三、完整的源代码
public class CircleProgressBar extends View {
private Paint mBackgroundPaint;//背景画笔
private Paint mProgressPaint;//进度画笔
private Paint textPaint; //文字画笔
private int mViewSize;
private int mMaxProgress = 100;//最大进度
private int mProgress = 0;//当前进度
private float ringWidth;//圆环宽度
public CircleProgressBar(Context context) {
this(context, null);
}
public CircleProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
int bgColor = context.getResources().getColor(R.color.c_f2efef);
int currentColor = context.getResources().getColor(R.color.m_red);
ringWidth = UtilHelper.INSTANCE.dip2px(context,4f);
if (attrs != null){
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar,0,0);
bgColor = ta.getColor(R.styleable.CircleProgressBar_cp_bg_color,context.getResources().getColor(R.color.c_f2efef));
currentColor = ta.getColor(R.styleable.CircleProgressBar_cp_current_color,context.getResources().getColor(R.color.m_red));
ringWidth = ta.getDimension(R.styleable.CircleProgressBar_cp_width,UtilHelper.INSTANCE.dip2px(context,4f));
ta.recycle();
}
mBackgroundPaint = new Paint();
mBackgroundPaint.setAntiAlias(true);
mBackgroundPaint.setColor(bgColor);
mBackgroundPaint.setStyle(Paint.Style.STROKE);
mBackgroundPaint.setStrokeWidth(ringWidth);
mProgressPaint = new Paint();
mProgressPaint.setAntiAlias(true);
mProgressPaint.setColor(currentColor);
mProgressPaint.setStyle(Paint.Style.STROKE);
mProgressPaint.setStrokeWidth(ringWidth);
//开始和结尾两端圆角
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
textPaint = new Paint();
textPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
int mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
if (mViewWidth > mViewHeight){
mViewSize = mViewWidth;
} else {
mViewSize = mViewHeight;
}
setMeasuredDimension(mViewSize,mViewSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画背景圆环
float radius = mViewSize/2 - ringWidth/2;
canvas.drawCircle(mViewSize/2,mViewSize/2,radius,mBackgroundPaint);
//画当前进度
float sweepAngle = 0;
if (mMaxProgress > 0) {
sweepAngle = 360*mProgress/mMaxProgress;
}
RectF rectF = new RectF(ringWidth/2,ringWidth/2,mViewSize-ringWidth/2,mViewSize-ringWidth/2);
canvas.drawArc(rectF,-90,sweepAngle,false,mProgressPaint);
//中心写进度文字
//将坐标原点移到控件中心
canvas.translate(getWidth()/2,getHeight()/2);
//先绘制当前的进度
textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),16));
textPaint.setColor(getContext().getResources().getColor(R.color.m_red));
//当前文字宽
float textCurrentWidth = textPaint.measureText(mProgress+"");
//绘制总的进度文字
textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),10));
float textMaxWidth = textPaint.measureText("/"+mMaxProgress);
textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),16));
float baseLineY = Math.abs(textPaint.ascent() + textPaint.descent()) / 2;
canvas.drawText(mProgress+"",-(textCurrentWidth+textMaxWidth)/2,baseLineY,textPaint);
textPaint.setTextSize(UtilHelper.INSTANCE.dip2px(getContext(),10));
textPaint.setColor(getContext().getResources().getColor(R.color.c_757575));
canvas.drawText("/"+mMaxProgress,-(textMaxWidth)/2+textCurrentWidth/2,baseLineY,textPaint);
}
/**
* @desc : 设置当前进度条
* @author : congge on 2020/2/18 17:40
**/
public void setmProgress(int mProgress,int mMaxProgress) {
this.mProgress = mProgress;
this.mMaxProgress = mMaxProgress;
invalidate();
}
}
总结:这是个很好的自定义控件学习范例,还不点个赞!!!
网友评论