1、首先绘制得底部的边框:
左右两个半圆环,中间上下两条平行线
//边框背景
mPaint.setColor(mProgressBankgroundColor);
mPaint.setStrokeWidth(mProgressBarFrameHeight);
//移动到第一个半圆圆心
canvas.translate(mRadius + mProgressBarFrameHeight, mProgressBarHeight / 2);
switch (mProgressBarBankgroundStyle) {
case SOLID:
//进度条实心
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(0, 0, mRadius, mPaint);
RectF rectF_Center = new RectF(0, -mRadius, mRectWidth, mRadius);
canvas.drawRect(rectF_Center, mPaint);
canvas.drawCircle(mRectWidth, 0, mRadius, mPaint);
break;
case SOLID_AND_FRAME:
//进度条实心加边框
mPaint.setStyle(Paint.Style.FILL);//FILL_AND_STROKE画时候 笔触右半边会和内容重合 差一半笔触!!!
float radiusTemp = mRadius + mProgressBarFrameHeight;
canvas.drawCircle(0, 0, radiusTemp, mPaint);
RectF rectF = new RectF(0, -radiusTemp, mRectWidth, radiusTemp);
canvas.drawRect(rectF, mPaint);
canvas.drawCircle(mRectWidth, 0, radiusTemp, mPaint);
break;
case HOLLOW:
//进度条空心
mPaint.setStyle(Paint.Style.STROKE);//STROKE画时候 笔触右半边会和内容重合 差一半笔触!!!
//
//画 左边半圆环
float newRadius = mRadius + mProgressBarFrameHeight / 2;
RectF rectF_Left_Right = new RectF(-newRadius, -newRadius, newRadius, newRadius);
canvas.drawArc(rectF_Left_Right, mStartAngle_LeftArc, 180, false, mPaint);
canvas.save();
canvas.translate(mRectWidth, 0);
//画 右边半圆环
canvas.drawArc(rectF_Left_Right, -mStartAngle_LeftArc, 180, false, mPaint);
canvas.restore();
//画 两条平行线
canvas.drawLine(0, -newRadius, mRectWidth, -newRadius, mPaint);
canvas.drawLine(0, newRadius, mRectWidth, newRadius, mPaint);
break;
}
2、绘制中间的填充进度
(1)画半圆左侧的任意部分,画个坐标系方便理解
float progressBarWidthNowTemp = mProgressLoadingWidth < mRadius ? mProgressLoadingWidth : mRadius;//当前进度条不能超过左边圆的半径
float leftArcWidth = progressBarWidthNowTemp;
RectF rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
/**
* ∠A 指的是 x轴和竖直切线的夹角 demo图见 https://code.aliyun.com/hi31588535/outside_chain/raw/master/blog_custom_view_show_pic.png
*/
double LinBian = mRadius - leftArcWidth;//直角三角形∠A邻边
double cosValue = LinBian / mRadius;//cosA=邻边/斜边
double radian = Math.acos(cosValue);//反余弦 返回值单位是弧度
// 用角度表示的角
double angle = Math.toDegrees(radian);//转化角度
float startAngle = (float) (mStartAngle_LeftArc + (90 - angle));
float sweepAngle = (float) angle * 2;
// Log.d(TAG, "onDraw: angle" + angle);//直角三角形 锐角A (∠A的) sinA=对边/斜边 cosA=邻边/斜边 tanA=对边/邻边
canvas.drawArc(rectF, startAngle, sweepAngle, false, mPaint);
(2)画中间矩形部分
float rectAndLeftArcMaxWidth = mProgressMaxWidth - mRadius;//所有进度条减去右边 就是左边和矩形
float progressBarWidthNowTemp = mProgressLoadingWidth < rectAndLeftArcMaxWidth ? mProgressLoadingWidth : rectAndLeftArcMaxWidth;
float rectWidth = progressBarWidthNowTemp - mRadius;//当前进度条减去左边半圆
rectWidth = rectWidth < rectAndLeftArcMaxWidth ? rectWidth : rectAndLeftArcMaxWidth;
RectF rectFCenter = new RectF(0, -mRadius, rectWidth, mRadius);
canvas.drawRect(rectFCenter, mPaint);
(3)画半圆右侧的任意部分 分2个圆弧 1个三角形
ps:这里直接放在之前画好的坐标系上,将就看看吧
float rectAndLeftArcMaxWidth = mProgressMaxWidth - mRadius;//所有进度条减去右边 就是左边和矩形
float progressBarWidthNowTemp = mProgressLoadingWidth < mProgressMaxWidth ? mProgressLoadingWidth : mProgressMaxWidth;
float rightArcWidth = progressBarWidthNowTemp - rectAndLeftArcMaxWidth;//当前进度条减去左边半圆和矩形
float rectWidth = rectAndLeftArcMaxWidth - mRadius;
canvas.translate(rectWidth, 0);//
RectF rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
double LinBian = rightArcWidth;//直角三角形∠B邻边
double cosValue = LinBian / mRadius;//cosB=邻边/斜边
double radian &