Android: looking for a drawArc() method with inner & outer radius

后端 未结 5 1724
逝去的感伤
逝去的感伤 2020-11-29 17:49

I have the following custom view:

\"alt

This I have achieved by using the Canvas\' drawArc

5条回答
  •  星月不相逢
    2020-11-29 18:13

    private static final float CIRCLE_LIMIT = 359.9999f;
    /**
     * Draws a thick arc between the defined angles, see {@link Canvas#drawArc} for more.
     * This method is equivalent to
     * 
    
     * float rMid = (rInn + rOut) / 2;
     * paint.setStyle(Style.STROKE); // there's nothing to fill
     * paint.setStrokeWidth(rOut - rInn); // thickness
     * canvas.drawArc(new RectF(cx - rMid, cy - rMid, cx + rMid, cy + rMid), startAngle, sweepAngle, false, paint);
     * 
    * but supports different fill and stroke paints. * * @param canvas * @param cx horizontal middle point of the oval * @param cy vertical middle point of the oval * @param rInn inner radius of the arc segment * @param rOut outer radius of the arc segment * @param startAngle see {@link Canvas#drawArc} * @param sweepAngle see {@link Canvas#drawArc}, capped at ±360 * @param fill filling paint, can be null * @param stroke stroke paint, can be null * @see Canvas#drawArc */ public static void drawArcSegment(Canvas canvas, float cx, float cy, float rInn, float rOut, float startAngle, float sweepAngle, Paint fill, Paint stroke) { if (sweepAngle > CIRCLE_LIMIT) { sweepAngle = CIRCLE_LIMIT; } if (sweepAngle < -CIRCLE_LIMIT) { sweepAngle = -CIRCLE_LIMIT; } RectF outerRect = new RectF(cx - rOut, cy - rOut, cx + rOut, cy + rOut); RectF innerRect = new RectF(cx - rInn, cy - rInn, cx + rInn, cy + rInn); Path segmentPath = new Path(); double start = toRadians(startAngle); segmentPath.moveTo((float)(cx + rInn * cos(start)), (float)(cy + rInn * sin(start))); segmentPath.lineTo((float)(cx + rOut * cos(start)), (float)(cy + rOut * sin(start))); segmentPath.arcTo(outerRect, startAngle, sweepAngle); double end = toRadians(startAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.arcTo(innerRect, startAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } }

    Can be extended to oval arc by duplicating rInn and rOut for x and y directions.

    Also wasn't part of the question, but to draw a text in the middle of a segment:

    textPaint.setTextAlign(Align.CENTER);
    Path midway = new Path();
    float r = (rIn + rOut) / 2;
    RectF segment = new RectF(cx - r, cy - r, cx + r, cy + r);
    midway.addArc(segment, startAngle, sweepAngle);
    canvas.drawTextOnPath("label", midway, 0, 0, textPaint);
    

提交回复
热议问题