如何为每一侧绘制具有不同填充和描边颜色的弧段?

时间:2015-01-08 22:24:29

标签: android

我从another SO question获得了此代码。我想知道如何修改它,以便连接圆圈和内圈周边的线条具有与外部颜色peremiter不同的颜色。说外圈的黑色和其他每个笔划都是灰色的。

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
 * <pre><code>
 * 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);
 * </code></pre>
 * 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 &plusmn;360
 * @param fill filling paint, can be <code>null</code>
 * @param stroke stroke paint, can be <code>null</code>
 * @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);
    }
}

基本上,函数参数最好是:

   public static void drawArcSegment(Canvas canvas, float cx, float cy, float rInn, float rOut, float startAngle, float sweepAngle, Paint fill, Paint strokeOutCircle, Paint StrokeAll) 

2 个答案:

答案 0 :(得分:0)

在绘制前设置颜色(例如在canvas.drawPath(segmentPath,fill)之前;)

离。

fill.setColor(Color.RED)
stroke.setColor(Color.GREEN)

你可以解析颜色

Color.parseColor("#FFFFFF")
// -> fill.setColor(Color.parseColor("#FFFFFF"));

或从资源导入

getResources().getColor(R.color.mycolor);
// -> fill.setColor(getResources().getColor(R.color.mycolor));

答案 1 :(得分:0)

您需要使用与填充范围相同的计算端点的draw*方法直接使用不同的颜料绘制环段的各个部分。虽然填充它仍然需要Path。我更进了一步,将您的strokeAll拆分为strokeSides + strokeOuter,以便更轻松地重复使用。考虑以下几行:

/**
 * Draws a thick arc between the defined angles, see {@link Canvas#drawArc} for more.
 * This method is equivalent to
 * <pre><code>
 * 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);
 * </code></pre>
 * but supports different fill and stroke paints.
 *
 * @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 &plusmn;360
 * @param fill filling paint, can be <code>null</code>
 * @param strokeInner stroke paint for inner ring segment, can be <code>null</code>
 * @param strokeOuter stroke paint for outer ring segment, can be <code>null</code>
 * @param strokeSides stroke paint for lines connecting the ends of the ring segments, can be <code>null</code>
 * @see Canvas#drawArc
 */
public static void drawArcSegment(Canvas canvas, float cx, float cy, float rInn, float rOut, float startAngle,
        float sweepAngle, Paint fill, Paint strokeInner, Paint strokeOuter, Paint strokeSides) {
    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);

    if (fill != null || strokeSides != null) { // to prevent calculating this lot of floats
        double start = toRadians(startAngle);
        double end = toRadians(startAngle + sweepAngle);
        float innerStartX = (float)(cx + rInn * cos(start));
        float innerStartY = (float)(cy + rInn * sin(start));
        float innerEndX = (float)(cx + rInn * cos(end));
        float innerEndY = (float)(cy + rInn * sin(end));
        float outerStartX = (float)(cx + rOut * cos(start));
        float outerStartY = (float)(cy + rOut * sin(start));
        float outerEndX = (float)(cx + rOut * cos(end));
        float outerEndY = (float)(cy + rOut * sin(end));
        if (fill != null) {
            Path segmentPath = new Path();
            segmentPath.moveTo(innerStartX, innerStartY);
            segmentPath.lineTo(outerStartX, outerStartY);
            segmentPath.arcTo(outerRect, startAngle, sweepAngle);
            // Path currently at outerEndX,outerEndY
            segmentPath.lineTo(innerEndX, innerEndY);
            segmentPath.arcTo(innerRect, startAngle + sweepAngle, -sweepAngle); // drawn backwards
            canvas.drawPath(segmentPath, fill);
        }
        if (strokeSides != null) {
            canvas.drawLine(innerStartX, innerStartY, outerStartX, outerStartY, strokeSides);
            canvas.drawLine(innerEndX, innerEndY, outerEndX, outerEndY, strokeSides);
        }
    }
    if (strokeInner != null) {
        canvas.drawArc(innerRect, startAngle, sweepAngle, false, strokeInner);
    }
    if (strokeOuter != null) {
        canvas.drawArc(outerRect, startAngle, sweepAngle, false, strokeOuter);
    }
}