studio programacion móviles drawarc desarrollo curso aplicaciones android 2d draw geometric-arc

móviles - manual de programacion android pdf



Android: buscando un método drawArc() con radio interior y exterior (4)

Puede intentar siguiendo ShapeDrawable

<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <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>

Tengo la siguiente vista personalizada:

Esto lo he logrado utilizando el método drawArc() Canvas. Sin embargo, con este método drawArc() no puedo limitar el radio interno del arco.

Lo que me gustaría tener es algo como esto:

donde solo queda un anillo exterior.

Lo que necesito es una función drawArc() donde pueda establecer el radio interior del arco. Alguien una idea de cómo hacer eso?

(Por cierto, pintar sobre el área interior no funciona, porque tiene que ser transparente. Pintar un círculo interno con Color.TRANSPARENT después de pintar los conos rojos y azules no elimina el color antiguo. Simplemente pone otra capa encima, que es transparente y a través del cual aún puedo ver el rojo y el azul)


Puede pintar sobre el área interior usando el PorterDuff xfermode llamado "Clear". Esto borrará los píxeles.


Puedes hacerlo:

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

La clave está en paint.setStyle(Paint.Style.STROKE); , recorta el centro del arco con el trazo que define en setStrokeWidth (en el ejemplo dibuja un arco con un radio de mRadius y 20px de grosor).

¡Espero eso ayude!


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

Puede extenderse a un arco ovalado duplicando rInn y rOut para las direcciones xey.

Además, no era parte de la pregunta, sino dibujar un texto en el medio de un 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, startAngle, sweepAngle); canvas.drawTextOnPath("label", midway, 0, 0, textPaint);