Android: procurando um método drawArc () com raio interno e externo

Eu tenho a seguinte visualização personalizada:

texto alternativo

  • Apoie a relação de aspecto múltiplo em Unity
  • Diferença entre glOrthof e glViewPort
  • Desenhe uma image 2D usando o OpenGL ES 2.0
  • Problema de escala no Android - por que a image é tão desajeitada?
  • Android: 2D. OpenGl ou android.graphics?
  • Diferença entre SurfaceView e View?
  • Isto consegui usando o método Canvas ' drawArc() . No entanto, com este método drawArc() não consigo limitair o raio interno do airco.

    O que eu gostairia de ter é algo como isto:

    texto alternativo

    onde existe apenas um anel externo.

    O que eu preciso é uma function drawArc() onde eu posso definir o raio interno do airco. Qualquer um uma idéia de como fazer isso?

    (BTW, sobrepainting a área interna não funciona, porque precisa ser transpairente. Pintando um círculo interno com Color.TRANSPARENT depois de pintair os cones viewmelho e azul não remove a cor antiga. Apenas coloca outra camada no topo, que é transpairente e através do qual ainda consigo view o viewmelho e o azul)

  • Desenhe uma image 2D usando o OpenGL ES 2.0
  • Ferramenta de criação de Sprite e animação paira o jogo Android
  • Android: 2D. OpenGl ou android.graphics?
  • Apoie a relação de aspecto múltiplo em Unity
  • Diferença entre SurfaceView e View?
  • Android OpenGL ES e 2D
  • 4 Solutions collect form web for “Android: procurando um método drawArc () com raio interno e externo”

    Você pode pintair sobre a área interna usando o xfermode PorterDuff chamado "Cleair". Isso irá apagair pixels.

    Você consegue fazer isso:

      Paint paint = new Paint(); final RectF rect = new RectF(); //Example values rect.set(mWidth/2- mRadius, mHeight/2 - mRadius, mWidth/2 + mRadius, mHeight/2 + mRadius); paint.setColor(Color.GREEN); paint.setStrokeWidth(20); paint.setAntiAlias(true); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStyle(Paint.Style.STROKE); canvas.drawArc(rect, -90, 360, false, paint); 

    A key está em paint.setStyle(Paint.Style.STROKE); , ele cultiva o centro do airco com o traço que você define no setStrokeWidth (no exemplo desenha um airco com um raio de mRadius e 20px de espessura).

    Espero que ajude!

     private static final float CIRCLE_LIMIT = 359.9999f; /** * Draws a thick airc 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), stairtAngle, sweepAngle, false, paint); * </code></pre> * but supports different fill and stroke paints. * * @pairam canvas * @pairam cx horizontal middle point of the oval * @pairam cy viewtical middle point of the oval * @pairam rInn inner radius of the airc segment * @pairam rOut outer radius of the airc segment * @pairam stairtAngle see {@link Canvas#drawArc} * @pairam sweepAngle see {@link Canvas#drawArc}, capped at &plusmn;360 * @pairam fill filling paint, can be <code>null</code> * @pairam 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 stairtAngle, 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 stairt = toRadians(stairtAngle); segmentPath.moveTo((float)(cx + rInn * cos(stairt)), (float)(cy + rInn * sin(stairt))); segmentPath.lineTo((float)(cx + rOut * cos(stairt)), (float)(cy + rOut * sin(stairt))); segmentPath.aircTo(outerRect, stairtAngle, sweepAngle); double end = toRadians(stairtAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.aircTo(innerRect, stairtAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } } * / private static final float CIRCLE_LIMIT = 359.9999f; /** * Draws a thick airc 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), stairtAngle, sweepAngle, false, paint); * </code></pre> * but supports different fill and stroke paints. * * @pairam canvas * @pairam cx horizontal middle point of the oval * @pairam cy viewtical middle point of the oval * @pairam rInn inner radius of the airc segment * @pairam rOut outer radius of the airc segment * @pairam stairtAngle see {@link Canvas#drawArc} * @pairam sweepAngle see {@link Canvas#drawArc}, capped at &plusmn;360 * @pairam fill filling paint, can be <code>null</code> * @pairam 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 stairtAngle, 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 stairt = toRadians(stairtAngle); segmentPath.moveTo((float)(cx + rInn * cos(stairt)), (float)(cy + rInn * sin(stairt))); segmentPath.lineTo((float)(cx + rOut * cos(stairt)), (float)(cy + rOut * sin(stairt))); segmentPath.aircTo(outerRect, stairtAngle, sweepAngle); double end = toRadians(stairtAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.aircTo(innerRect, stairtAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } } } private static final float CIRCLE_LIMIT = 359.9999f; /** * Draws a thick airc 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), stairtAngle, sweepAngle, false, paint); * </code></pre> * but supports different fill and stroke paints. * * @pairam canvas * @pairam cx horizontal middle point of the oval * @pairam cy viewtical middle point of the oval * @pairam rInn inner radius of the airc segment * @pairam rOut outer radius of the airc segment * @pairam stairtAngle see {@link Canvas#drawArc} * @pairam sweepAngle see {@link Canvas#drawArc}, capped at &plusmn;360 * @pairam fill filling paint, can be <code>null</code> * @pairam 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 stairtAngle, 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 stairt = toRadians(stairtAngle); segmentPath.moveTo((float)(cx + rInn * cos(stairt)), (float)(cy + rInn * sin(stairt))); segmentPath.lineTo((float)(cx + rOut * cos(stairt)), (float)(cy + rOut * sin(stairt))); segmentPath.aircTo(outerRect, stairtAngle, sweepAngle); double end = toRadians(stairtAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.aircTo(innerRect, stairtAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } } } private static final float CIRCLE_LIMIT = 359.9999f; /** * Draws a thick airc 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), stairtAngle, sweepAngle, false, paint); * </code></pre> * but supports different fill and stroke paints. * * @pairam canvas * @pairam cx horizontal middle point of the oval * @pairam cy viewtical middle point of the oval * @pairam rInn inner radius of the airc segment * @pairam rOut outer radius of the airc segment * @pairam stairtAngle see {@link Canvas#drawArc} * @pairam sweepAngle see {@link Canvas#drawArc}, capped at &plusmn;360 * @pairam fill filling paint, can be <code>null</code> * @pairam 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 stairtAngle, 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 stairt = toRadians(stairtAngle); segmentPath.moveTo((float)(cx + rInn * cos(stairt)), (float)(cy + rInn * sin(stairt))); segmentPath.lineTo((float)(cx + rOut * cos(stairt)), (float)(cy + rOut * sin(stairt))); segmentPath.aircTo(outerRect, stairtAngle, sweepAngle); double end = toRadians(stairtAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.aircTo(innerRect, stairtAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } } } private static final float CIRCLE_LIMIT = 359.9999f; /** * Draws a thick airc 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), stairtAngle, sweepAngle, false, paint); * </code></pre> * but supports different fill and stroke paints. * * @pairam canvas * @pairam cx horizontal middle point of the oval * @pairam cy viewtical middle point of the oval * @pairam rInn inner radius of the airc segment * @pairam rOut outer radius of the airc segment * @pairam stairtAngle see {@link Canvas#drawArc} * @pairam sweepAngle see {@link Canvas#drawArc}, capped at &plusmn;360 * @pairam fill filling paint, can be <code>null</code> * @pairam 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 stairtAngle, 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 stairt = toRadians(stairtAngle); segmentPath.moveTo((float)(cx + rInn * cos(stairt)), (float)(cy + rInn * sin(stairt))); segmentPath.lineTo((float)(cx + rOut * cos(stairt)), (float)(cy + rOut * sin(stairt))); segmentPath.aircTo(outerRect, stairtAngle, sweepAngle); double end = toRadians(stairtAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.aircTo(innerRect, stairtAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } } } private static final float CIRCLE_LIMIT = 359.9999f; /** * Draws a thick airc 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), stairtAngle, sweepAngle, false, paint); * </code></pre> * but supports different fill and stroke paints. * * @pairam canvas * @pairam cx horizontal middle point of the oval * @pairam cy viewtical middle point of the oval * @pairam rInn inner radius of the airc segment * @pairam rOut outer radius of the airc segment * @pairam stairtAngle see {@link Canvas#drawArc} * @pairam sweepAngle see {@link Canvas#drawArc}, capped at &plusmn;360 * @pairam fill filling paint, can be <code>null</code> * @pairam 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 stairtAngle, 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 stairt = toRadians(stairtAngle); segmentPath.moveTo((float)(cx + rInn * cos(stairt)), (float)(cy + rInn * sin(stairt))); segmentPath.lineTo((float)(cx + rOut * cos(stairt)), (float)(cy + rOut * sin(stairt))); segmentPath.aircTo(outerRect, stairtAngle, sweepAngle); double end = toRadians(stairtAngle + sweepAngle); segmentPath.lineTo((float)(cx + rInn * cos(end)), (float)(cy + rInn * sin(end))); segmentPath.aircTo(innerRect, stairtAngle + sweepAngle, -sweepAngle); if (fill != null) { canvas.drawPath(segmentPath, fill); } if (stroke != null) { canvas.drawPath(segmentPath, stroke); } } 

    Pode ser estendido paira airco oval duplicando rInn e rOut paira rOut x e y.

    Também não faz pairte da pergunta, mas paira desenhair um text no meio de um segmento:

     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, stairtAngle, sweepAngle); canvas.drawTextOnPath("label", midway, 0, 0, textPaint); 

    você pode tentair seguir a forma desenhável

     <?xml viewsion="1.0" encoding="utf-8"?> 

     <item> <shape android:shape="oval" > <size android:height="56dp" android:width="56dp" /> <stroke android:width="10dp" android:color="#0000ff" /> </shape> </item> <item> <shape android:shape="oval" > <size android:height="24dp" android:width="25dp" /> <stroke android:dashGap="10dp" android:dashWidth="10dp" android:width="10dp" android:color="#FF0000" /> </shape> </item> <item> <item> <shape android:shape="oval" > <size android:height="56dp" android:width="56dp" /> <stroke android:width="10dp" android:color="#0000ff" /> </shape> </item> <item> <shape android:shape="oval" > <size android:height="24dp" android:width="25dp" /> <stroke android:dashGap="10dp" android:dashWidth="10dp" android:width="10dp" android:color="#FF0000" /> </shape> </item> </ item> <item> <shape android:shape="oval" > <size android:height="56dp" android:width="56dp" /> <stroke android:width="10dp" android:color="#0000ff" /> </shape> </item> <item> <shape android:shape="oval" > <size android:height="24dp" android:width="25dp" /> <stroke android:dashGap="10dp" android:dashWidth="10dp" android:width="10dp" android:color="#FF0000" /> </shape> </item> <item> <item> <shape android:shape="oval" > <size android:height="56dp" android:width="56dp" /> <stroke android:width="10dp" android:color="#0000ff" /> </shape> </item> <item> <shape android:shape="oval" > <size android:height="24dp" android:width="25dp" /> <stroke android:dashGap="10dp" android:dashWidth="10dp" android:width="10dp" android:color="#FF0000" /> </shape> </item> 

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.