效果预览
实现
attrs文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="textColor" format="color"/>
<attr name="textSize" format="dimension"/>
<attr name="minNumber" format="integer"/>
<attr name="maxNumber" format="integer"/>
<attr name="currentNumber" format="integer"/>
<attr name="bgColor" format="color"/>
<attr name="foreColor" format="color"/>
<attr name="strokeWidth" format="dimension"/>
<declare-styleable name="StepView">
<attr name="textColor"/>
<attr name="textSize"/>
<attr name="minNumber"/>
<attr name="maxNumber"/>
<attr name="bgColor"/>
<attr name="foreColor"/>
<attr name="strokeWidth"/>
<attr name="currentNumber"/>
</declare-styleable>
</resources>
创建自定义View
public StepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StepView);
textColor = typedArray.getColor(R.styleable.StepView_textColor, textColor);
textSize = typedArray.getDimensionPixelSize(
R.styleable.StepView_textSize,
dip2px(context, textSize));
minNumber = typedArray.getInt(R.styleable.StepView_minNumber, minNumber);
maxNumber = typedArray.getInt(R.styleable.StepView_maxNumber, maxNumber);
currentStep = typedArray.getInt(R.styleable.StepView_currentNumber, currentStep);
if (currentStep < minNumber) currentStep = minNumber;
if (currentStep > maxNumber) currentStep = maxNumber;
bgColor = typedArray.getColor(R.styleable.StepView_bgColor, bgColor);
foreColor = typedArray.getColor(R.styleable.StepView_foreColor, foreColor);
strokeWidth = typedArray.getDimensionPixelSize(
R.styleable.StepView_strokeWidth,
dip2px(context, strokeWidth));
initPaint();
typedArray.recycle();
}
private void initPaint() {
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(textSize);
textPaint.setColor(textColor);
bgPaint = new Paint();
bgPaint.setAntiAlias(true);
bgPaint.setColor(bgColor);
bgPaint.setStrokeWidth(strokeWidth);
bgPaint.setStyle(Paint.Style.STROKE);
bgPaint.setStrokeCap(Paint.Cap.ROUND);
forePaint = new Paint();
forePaint.setAntiAlias(true);
forePaint.setColor(foreColor);
forePaint.setStrokeWidth(strokeWidth);
forePaint.setStyle(Paint.Style.STROKE);
forePaint.setStrokeCap(Paint.Cap.ROUND);
}
Rect textBounds = new Rect();
int width = 0;
int height = 0;
RectF rectF;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (width == 0 || height == 0) {
width = getMeasuredWidth();
height = getMeasuredHeight();
if (width > height) {
width = height;
} else {
height = width;
}
rectF = new RectF(strokeWidth/2f, strokeWidth/2f, width - strokeWidth/2f, height - strokeWidth/2f);
}
String currentStepString = String.valueOf(currentStep);
textPaint.getTextBounds(currentStepString, 0, currentStepString.length(), textBounds);
int startPosition = width/2 - textBounds.width()/2;
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float dy = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
float baseLine = height/2f + dy;
canvas.drawText(currentStepString, startPosition, baseLine, textPaint);
canvas.drawArc(rectF, 135, 270, false, bgPaint);
float rate = currentStep * 1f / maxNumber;
if (rate < 0) rate = 0;
if (rate > 1) rate = 1;
canvas.drawArc(rectF, 135, 270 * rate, false, forePaint);
}
重点讲解
获取属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StepView);
textColor = typedArray.getColor(R.styleable.StepView_textColor, textColor);
typedArray.recycle();
计算文字位置
计算baseLine
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float dy = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
float baseLine = height/2f + dy;
计算文字开横坐标
Rect textBounds = new Rect();
textPaint.getTextBounds(currentStepString, 0, currentStepString.length(), textBounds);
int startPosition = width/2 - textBounds.width()/2;