我可能有些晚了,但是我实际上编写了一个自定义组件,其中有两个环,看起来与您试图实现的相似。您可以轻松地删除外部环。最终我得到的图像:
![enter image description here](https://istack.dev59.com/aDhQ6.webp)
这是类:
public class RoundedSectionProgressBar extends View {
private static final float DIVIDER_ANGLE = 7;
public static final float DEGREES_IN_CIRCLE = 360;
public static final int PADDING = 18;
public static final int PADDING2 = 12;
protected final Paint paint = new Paint();
protected final Paint waitingPaint = new Paint();
protected final Paint backgroundPaint = new Paint();
private int totalSections = 5;
private int fullSections = 2;
private int waiting = 3;
private RectF rect = new RectF();
public RoundedSectionProgressBar(Context context) {
super(context);
init(context, null);
}
public RoundedSectionProgressBar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RoundedSectionProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
int strokeWidth = 3;
setupPaint(context, strokeWidth, paint, R.color.filled_color_inner_ring);
setupPaint(context, strokeWidth, waitingPaint, R.color.empty_color_inner_ring);
setupPaint(context, strokeWidth, backgroundPaint, R.color.filled_color_outer_ring);
}
private void setupPaint(Context context, int strokeWidth, Paint backgroundPaint, int colorRes) {
backgroundPaint.setStrokeCap(Paint.Cap.SQUARE);
backgroundPaint.setColor(context.getResources().getColor(colorRes));
backgroundPaint.setAntiAlias(true);
backgroundPaint.setStrokeWidth(strokeWidth);
backgroundPaint.setStyle(Paint.Style.STROKE);
}
public int getTotalSections() {
return totalSections;
}
public void setTotalSections(int totalSections) {
this.totalSections = totalSections;
invalidate();
}
public int getFullSections() {
return fullSections;
}
public void setNumberOfSections(int fullSections, int totalSections, int waiting) {
this.fullSections = fullSections;
this.totalSections = totalSections;
this.waiting = waiting;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
rect.set(getLeft() + PADDING, getTop() + PADDING, getRight() - PADDING, getBottom() - PADDING);
float angleOfSection = (DEGREES_IN_CIRCLE / totalSections) - DIVIDER_ANGLE;
for (int i = 0; i < totalSections; i++) {
float startAngle = -90 + i * (angleOfSection + DIVIDER_ANGLE) + DIVIDER_ANGLE / 2;
if (i < fullSections) {
canvas.drawArc(rect, startAngle, angleOfSection, false, paint);
} else {
canvas.drawArc(rect, startAngle, angleOfSection, false, backgroundPaint);
}
}
rect.set(getLeft() + PADDING2, getTop() + PADDING2, getRight() - PADDING2, getBottom() - PADDING2);
for (int i = 0; i < waiting; i++) {
float startAngle = -90 + i * (angleOfSection + DIVIDER_ANGLE) + DIVIDER_ANGLE / 2;
canvas.drawArc(rect, startAngle, angleOfSection, false, waitingPaint);
}
}
}
请注意,该代码不会给出外圈的“空”插槽,因为最终我们决定不使用它们。内圆将同时拥有空和填充插槽。整个类可以重复使用,只负责绘制的两个环,
6/6
,
+3
和红色圆圈是另一个视图的一部分。
代码中最重要的部分是
onDraw
方法。它包含循环中绘制弧形的逻辑,以及计算角度并在它们之间添加空格的逻辑。一切都被旋转了-90度,因为我需要它从顶部开始,而不是像Android中的0度角在右侧。它并不复杂,如果需要,您可以修改它以更好地适应您的需求。
Canvas#drawArc
。 - pskink