1.自定义 View 的基本流程
- 创建 View Class
- 创建 attr 属性文件,确定属性
- View Class 绑定 attr 属性
- onMeasure 测量
- onDraw 绘制
1.1 创建 View Class
public class ArcView extends View {
public ArcView(Context context) {
this(context, null);
}
public ArcView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
1.2 创建 attr 属性
1.3 绑定属性
private void initAttr(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ArcView);
//外环颜色
mInnerColor = array.getColor(R.styleable.ArcView_arcInnerColor, mInnerColor);
//内环颜色
mOutColor = array.getColor(R.styleable.ArcView_arcOutColor, mOutColor);
//环大小
mWidth = (int) array.getDimension(R.styleable.ArcView_arcWidth, mWidth);
//文字
mText = array.getString(R.styleable.ArcView_arcText);
//文字大小
mTextSize = array.getDimensionPixelSize(R.styleable.ArcView_arcTextSize, mTextSize);
//文字颜色
mTextColor = array.getColor(R.styleable.ArcView_arcTextColor, mTextColor);
array.recycle();
}
1.4 onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//确保正方形,将短边的大小设为狂傲
//宽
int width = MeasureSpec.getSize(widthMeasureSpec);
//高
int height = MeasureSpec.getSize(heightMeasureSpec);
//设置宽高
setMeasuredDimension(Math.min(width, height), Math.min(width, height));
}
1.5 onDraw
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
- 第一步,画内环
private void initInnerPaint() {
mInnerPaint = new Paint();
//抗锯齿
mInnerPaint.setAntiAlias(true);
//防抖动
mInnerPaint.setDither(true);
//宽度
mInnerPaint.setStrokeWidth(mWidth);
//颜色
mInnerPaint.setColor(mInnerColor);
//设置状态
mInnerPaint.setStyle(Paint.Style.STROKE);
//头部小圆点
mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画内环
RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
}
- 第二步,画外环
private void initOutPaint() {
mOutPaint = new Paint();
//抗锯齿
mOutPaint.setAntiAlias(true);
//防抖动
mOutPaint.setDither(true);
//宽度
mOutPaint.setStrokeWidth(mWidth);
//颜色
mOutPaint.setColor(mOutColor);
//设置状态
mOutPaint.setStyle(Paint.Style.STROKE);
//头部小圆点
mOutPaint.setStrokeCap(Paint.Cap.ROUND);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画内环
RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
//画内环
if (MaxProgress == 0) return;
float sweepAngle = (float) CurrentProgress / MaxProgress;
canvas.drawArc(rectF, 135, sweepAngle * 270, false, mOutPaint);
}
- 第三步,画文字
private void initTextPaint() {
mTextPaint = new Paint();
//抗锯齿
mTextPaint.setAntiAlias(true);
//文字大小
mTextPaint.setTextSize(mTextSize);
//文字颜色
mTextPaint.setColor(mTextColor);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画内环
RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
//画内环
if (MaxProgress == 0) return;
float sweepAngle = (float) CurrentProgress / MaxProgress;
canvas.drawArc(rectF, 135, sweepAngle * 270, false, mOutPaint);
//画文字
//测量文字宽度
Rect rect = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), rect);
int x = getWidth() / 2 - rect.width() / 2;
//基线
Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
int y = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
int baseline = getHeight() / 2 + y;
canvas.drawText(mText, x, baseline, mTextPaint);
}
自定义圆弧就介绍到这里了,如果有什么写得不对的,可以在下方评论留言,我会第一时间改正。
Github 源码链接