这个进度条是一个月前写的,现在挖出来。
这是一个类似仪表盘的原型进度条:
如果进度大于零,它就会从弧外部左下角开始增长(不与这个弧重叠,这个弧是基线),会有一个动画。
这里涉及到画圆的知识,还有动画。动画的实现我市直接在onDraw中进行更改再调用invalidate()实现的。
好,首先是各种变量:
/**
* 进度条基线颜色与进度条颜色
*/
private int baseArcColor = 0xff69b6e4, progressColor = 0xffffda2c;
/**
* 进度条基线宽度与进度条宽度(px)
*/
private int baseArcWidth = 2, progressWidth = 10;
/**
* 进度条基线画笔与进度条画笔
*/
private Paint baseArcPaint, progressPaint;
/**
* 进度条进度(min = 0, max = 100)
*/
private float progress = 0;
/**
* 绘制起始位置(>90)系统默认的起始位置是x轴正方向
* 改变位置时以顺时针方向相加相应的度数
*/
private int startDegree = 145;
/**
* 执行动画使用的当前进度与总共前进的进度
*/
private float currentProgress = 0, sweepProgress = 0;
private float totalSweepProgress = 0;
/**
* 绘图区域
*/
private RectF area, innerArea;
初始化方法:
private void initView() {
baseArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
baseArcPaint.setStyle(Paint.Style.STROKE);
baseArcPaint.setColor(baseArcColor);
baseArcPaint.setStrokeWidth(baseArcWidth);
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setColor(progressColor);
progressPaint.setStrokeWidth(progressWidth);
progressPaint.setStrokeCap(Paint.Cap.ROUND);
totalSweepProgress = 360 - (startDegree - 90) * 2;
setProgress(0);
}
setProgress()方法:
public void setProgress(float progress) {
this.progress = progress;
sweepProgress = progress / 100 * totalSweepProgress;
invalidate();
}
其次,onMeasure,我们设置它是是一个自适应的正方形:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.EXACTLY) {
height = width;
} else if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.AT_MOST) {
height = width;
} else {
if (height == 0) height = width;
if (width == 0) width = height;
if (height > width) {
height = width;
} else {
width = height;
}
}
setMeasuredDimension(width, height);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
area = new RectF(0, 0, w - progressWidth, h - progressWidth);
area.offset(progressWidth / 2, progressWidth / 2);
innerArea = new RectF(0, 0, w - progressWidth * 3 / 2, h - progressWidth * 3 / 2);
innerArea.offset(progressWidth * 3 / 4, progressWidth * 3 / 4);
}
在onDraw中绘制:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制基线
canvas.drawArc(innerArea, startDegree, totalSweepProgress, false, baseArcPaint);
//绘制进度
if (progress > 0) {
currentProgress += 2;
if (currentProgress > totalSweepProgress) currentProgress = totalSweepProgress;
canvas.drawArc(area, startDegree, currentProgress, false, progressPaint);
if (currentProgress < sweepProgress) {
invalidate();
//postInvalidateDelayed(10);
}
}
}