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 ±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 ±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 ±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);
}
}