1.自定义属性
首先有没有自定义属性,比如这里的圆环的宽度,外圆的颜色,中间文字的大小和颜色都不是写死的,所以需要自定义属性
<resources>
<declare-styleable name="ProgressBar">
<!--圆环宽度-->
<attr name="ringWidth" format="dimension" />
<!--外圆颜色-->
<attr name="outCircleColor" format="color" />
<!--进度圆颜色-->
<attr name="innerCircleColor" format="color" />
<!--中间文字的大小-->
<attr name="centerTextSize" format="dimension" />
<!--中间文字的颜色-->
<attr name="centerTextColor" format="color" />
</declare-styleable>
</resources>
public ProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取自定义属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressBar);
mRingWidth = typedArray.getDimensionPixelOffset(R.styleable.ProgressBar_ringWidth,
DimenUtils.dip2px(context, mRingWidth));
mOutCircleColor = typedArray.getColor(R.styleable.ProgressBar_outCircleColor, mOutCircleColor);
mInnerCircleColor = typedArray.getColor(R.styleable.ProgressBar_innerCircleColor, mInnerCircleColor);
mCenterTextSize = typedArray.getDimensionPixelOffset(R.styleable.ProgressBar_centerTextSize,
DimenUtils.dip2px(context, mCenterTextSize));
mCenterTextColor = typedArray.getColor(R.styleable.ProgressBar_centerTextColor, mCenterTextColor);
typedArray.recycle();
}
2. 测量
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//默认大小
int defaultSize = DimenUtils.dip2px(getContext(), 100);
//宽度
//获取模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
//获取大小
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
//包裹内容
if (widthMode == MeasureSpec.AT_MOST) {
widthSize = defaultSize;
}
//高度
//获取模式
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//获取大小
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//包裹内容
if (heightMode == MeasureSpec.AT_MOST) {
heightSize = defaultSize;
}
//宽高要一致
int progressSize = Math.min(widthSize, heightSize);
//设置宽高
setMeasuredDimension(progressSize, progressSize);
}
3.绘制
3.1 绘制外圆
@Override
protected void onDraw(Canvas canvas) {
// 1.绘制外圆
int cx = getWidth() / 2;
int cy = getHeight() / 2;
float radius = getWidth() / 2 - mRingWidth / 2;
canvas.drawCircle(cx, cy, radius, mOutCirclePaint);
}
3.2 绘制进度圆
@Override
protected void onDraw(Canvas canvas) {
//2.绘制进度圆
float currentProgress = (float) (mCurrentPercentage * 360);
if (mOval == null) {
mOval = new RectF(mRingWidth / 2, mRingWidth / 2,
getWidth() - mRingWidth / 2, getHeight() - mRingWidth / 2);
}
canvas.drawArc(mOval, 0, currentProgress, false, mInnerCirclePaint);
}
3.3 绘制中间文本
protected void onDraw(Canvas canvas) {
//3.绘制中间文本
String text = (int) (mCurrentPercentage * 100) + "%";
//字体的宽度高度
if (mBounds == null) {
mBounds = new Rect();
}
mCenterTextPaint.getTextBounds(text, 0, text.length(), mBounds);
float x = getWidth() / 2 - mBounds.width() / 2;
//知道中间位置求基线位置
Paint.FontMetricsInt fontMetricsInt = mCenterTextPaint.getFontMetricsInt();
//指定中间位置,绘制文本
int baseLine = getHeight() / 2 + (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
canvas.drawText(text, x, baseLine, mCenterTextPaint);
}
完整代码:progressbar