Android 如何为每一侧绘制具有不同填充和笔划颜色的圆弧段?

Android 如何为每一侧绘制具有不同填充和笔划颜色的圆弧段?,android,Android,我从你那里得到了这个密码。我想知道如何修改它,使连接圆和内圆周长的线具有不同于外圆周长的颜色。表示外圆为黑色,每隔一笔为灰色 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&g

我从你那里得到了这个密码。我想知道如何修改它,使连接圆和内圆周长的线具有不同于外圆周长的颜色。表示外圆为黑色,每隔一笔为灰色

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);
    }
}
*但支持不同的填充和笔划绘制。 * *@param画布 *@param cx椭圆形的水平中点 *@param cy椭圆形的垂直中点 *@param rInn弧段的内半径 *@param rOut弧段的外半径 *@param startAngle见{@link Canvas#drawArc} *@param sweepAngle见{@link Canvas#drawArc},封顶在±;360 *@param fill-filling-paint,可以是
null
*@param stroke-stroke-paint,可以是
null
*@见画布#drawArc */ 公共静态无效drawArcSegment(画布画布、浮动cx、浮动cy、浮动rInn、浮动rOut、浮动startAngle、, 浮动扫掠角、油漆填充、油漆冲程){ 如果(扫掠角度>圆的极限){ 扫掠角=圆_极限; } if(扫掠角<-圆限制){ 扫掠角=-圆\极限; } RectF outerRect=新的RectF(cx-rOut,cy-rOut,cx+rOut,cy+rOut); RectF innerRect=新的RectF(cx-rInn,cy-rInn,cx+rInn,cy+rInn); 路径段路径=新路径(); 双启动=环面(星缠结); 分段路径。移动到((浮动)(cx+rInn*cos(开始)),(浮动)(cy+rInn*sin(开始)); 线段路径行到((浮动)(cx+rOut*cos(开始)),(浮动)(cy+rOut*sin(开始)); 分段路径.arcTo(外纠正、星形纠结、扫描角); 双端=环面(星形缠绕+扫掠角); 线段路径lineTo((浮点)(cx+rInn*cos(end)),(浮点)(cy+rInn*sin(end)); arcTo(innerRect,startAngle+扫描角度,-扫描角度); 如果(填充!=null){ 画布.绘图路径(分段路径,填充); } 如果(笔划!=null){ canvas.drawPath(分段路径、笔划); } } 基本上,函数参数在理想情况下如下所示:

fill.setColor(Color.RED)
stroke.setColor(Color.GREEN)
在绘制之前设置颜色(例如,在画布之前。绘制路径(分段路径,填充);)

你可以解析颜色

getResources().getColor(R.color.mycolor);
// -> fill.setColor(getResources().getColor(R.color.mycolor));
或从资源中导入

/**
 * 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);
    }
}

您需要直接通过
draw*
方法从与填充边界相同的计算端点,使用不同的油漆分别绘制环段的各个部分。不过,仍然需要
路径来填充它。我更进一步,将您的
strokeAll
拆分为
strokeSides
+
strokeOuter
,以便于重用。考虑下面的一行:

*但支持不同的填充和笔划绘制。 * *@param cx椭圆形的水平中点 *@param cy椭圆形的垂直中点 *@param rInn弧段的内半径 *@param rOut弧段的外半径 *@param startAngle见{@link Canvas#drawArc} *@param sweepAngle见{@link Canvas#drawArc},封顶在±;360 *@param fill-filling-paint,可以是
null
*@param strokeInner笔划内环段油漆,可
null
*@param strokeOuter stroke用于外圈段的绘制,可以是
null
*@param strokeSides用于连接环段末端的线条的笔划绘制,可以
null
*@见画布#drawArc */ 公共静态无效drawArcSegment(画布画布、浮动cx、浮动cy、浮动rInn、浮动rOut、浮动startAngle、, 浮子扫掠角、油漆填充、油漆冲程内、油漆冲程外、油漆冲程侧){ 如果(扫掠角度>圆的极限){ 扫掠角=圆_极限; } if(扫掠角<-圆限制){ 扫掠角=-圆\极限; } RectF outerRect=新的RectF(cx-rOut,cy-rOut,cx+rOut,cy+rOut); RectF innerRect=新的RectF(cx-rInn,cy-rInn,cx+rInn,cy+rInn); 如果(fill!=null | | strokeSides!=null){//以防止计算这一批浮点 双启动=环面(星缠结); 双端=环面(星形缠绕+扫掠角); 浮点innerStartX=(浮点)(cx+rInn*cos(开始)); float innerStartY=(float)(cy+rInn*sin(start)); 浮动内端x=(浮动)(cx+rInn*cos(结束)); float innendy=(float)(cy+rInn*sin(end)); float outerStartX=(float)(cx+路由*cos(开始)); 浮球外侧起点=(浮球)(cy+rOut*sin(起点)); float outerEndX=(float)(cx+rOut*cos(end)); float outerEndY=(float)(cy+rOut*sin(end)); 如果(填充!=null){ 路径段路径=新路径(); segmentPath.moveTo(innerStartX,innerStartY); segmentPath.lineTo(outerStartX,outerStartY); 分段路径.arcTo(外纠正、星形纠结、扫描角); //当前位于outerEndX、outerEndY的路径 lineTo(innerEndX,innerEndY); segmentPath.arcTo(innerRect,startAngle+sweepAngle,-sweepAngle);//向后绘制 画布.绘图路径(分段路径,填充); } 如果(选通侧!=null){ 帆布.抽绳(innerStartX、innerStartY、outerStartX、outerStartY、strokeSides); 画布.抽绳(内端X、内端Y、外端X、外端Y、strokeSides); } } if(strokeInner!=null){ 画布.drawArc(innerRect、startAngle、sweepAngle、false、strokeInner); } 如果(strokeOuter!=null){ 画布.绘制弧(外部正确、星形缠绕、扫掠角、假、笔划外部); } }
请您解释该代码的机制,如果它与任何其他类有任何关联,请仔细阅读问题。我说的是在“特定”分段上设置颜色。并非所有分段都应该是另一个画布绘制,在其中设置颜色、分割代码。上面的代码绘制了完整的路径,因此它为什么会获得笔划颜色。您将如何更改上述代码以符合o的要求
getResources().getColor(R.color.mycolor);
// -> fill.setColor(getResources().getColor(R.color.mycolor));
/**
 * 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);
    }
}