大概就是所有困难都是自我脑补和自我畏惧,自定义控件很早之前自己以为非常难,不愿意触碰,但是不接触就是永远不会,写多了就会了,上代码:
/**
* @Author: WinSinMin
* @Email: winsinmin@foxmail.com
* @CreateDate: 2019/6/26 14:56
* @Description: 自定义环形进度条
*/
public class CircleProgressBar extends View {
private int currentValue = 0;
private float alphaAngle;
private int backColor;
private int fillColor;
private int circleWidth;
private int viewWidth;
private Paint circlePaint;
private ValueAnimator animator;
private RectF oval;
private boolean isStart = false;
public CircleProgressBar(Context context) {
this(context, null);
}
public CircleProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.circleProgressBar, defStyleAttr, 0);
if (ta != null) {
fillColor = ta.getColor(R.styleable.circleProgressBar_fillColor, Color.parseColor("#DDDDDD")); // 默认底色为亮灰色
backColor = ta.getColor(R.styleable.circleProgressBar_backColor, Color.parseColor("#FF401A")); // 默认进度条颜色为蓝色
circleWidth = ta.getDimensionPixelSize(R.styleable.circleProgressBar_circleWidth, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6, getResources().getDisplayMetrics())); // 默认圆弧宽度为6dp
ta.recycle();
}
circlePaint = new Paint();
circlePaint.setAntiAlias(true); // 抗锯齿
circlePaint.setDither(true); // 防抖动
circlePaint.setStrokeWidth(circleWidth);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
viewWidth = Math.min(measureWidth, measureHeight);
setMeasuredDimension(viewWidth, viewWidth);
oval = new RectF(circleWidth / 2, circleWidth / 2, viewWidth - circleWidth / 2, viewWidth - circleWidth / 2); // 圆的外接正方形
}
@Override
protected void onDraw(Canvas canvas) {
circlePaint.setColor(backColor); // 设置底部圆环的颜色,这里使用第一种颜色
circlePaint.setStyle(Paint.Style.STROKE); // 设置绘制的圆为空心
canvas.drawCircle(viewWidth / 2, viewWidth / 2, viewWidth / 2 - circleWidth / 2, circlePaint); // 画底部的空心圆
circlePaint.setColor(fillColor); // 设置圆弧的颜色
circlePaint.setStrokeCap(Paint.Cap.ROUND); // 把每段圆弧改成圆角的
alphaAngle = currentValue * 1.0f; // 计算每次画圆弧时扫过的角度,这里计算要注意分母要转为float类型,否则alphaAngle永远为0
canvas.drawArc(oval, -90, alphaAngle, false, circlePaint);
}
public void startProgress(long duration) {
if (isStart)
return;
animator = ValueAnimator.ofInt(0, 360);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentValue = (int) animation.getAnimatedValue();
invalidate();
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
isStart = false;
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animator.setInterpolator(new LinearInterpolator());
animator.setDuration(duration);
animator.start();
isStart = true;
}
public void cancel() {
if (animator != null || animator.isRunning()) {
animator.cancel();
isStart = false;
}
}
public void pause() {
if (animator != null || animator.isRunning()) {
animator.pause();
}
}
public void resume() {
if (animator != null || animator.isPaused()) {
animator.resume();
}
}
}
attrs文件中新增
<declare-styleable name="circleProgressBar">
<attr name="circleWidth" format="dimension" />
<attr name="fillColor" format="reference|color" />
<attr name="backColor" format="reference|color" />
</declare-styleable>
调用的话直接调用startProgress就行了。