Canvas.drawArc () artefactos

Dibujo un arco sobre lienzo en una vista personalizada como se muestra a continuación. Paint y el rectangle se definen fuera de onDraw() y se añaden allí con fines de simplicidad.

 protected void onDraw(Canvas canvas) { super.onDraw(canvas); RectF rectangle = new RectF(60f, 60f, 480f, 480f); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(0x40000000); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(120); canvas.drawArc(rectangle, 225f, 315f, false, paint); } 

Cuando ejecuto este código en Galaxy Nexus con 4.3, hay siguientes artefactos. Introduzca aquí la descripción de la imagen

No hay tales artefactos cuando se ejecuta en Nexus 5 con 4.4.4 sin embargo. Introduzca aquí la descripción de la imagen

Observé tales artefactos por ángulos como (225f, 315f) y algunos otros ángulos solamente. La mayor parte del tiempo el arco tiene una forma correcta.

¿Hay alguna manera de evitar esos artefactos?

Actualización: He intentado usar software, hardware y ninguna capa usando setLayerType() . Los artefactos cambiaron su forma, pero todavía estaban presentes.

Soy un novato StackOverflow, quería añadir un comentario pero no podía (tener puntos insuficientes) así que tuve que poner mi comentario en una respuesta!

Una cosa extraña es que el arco sobrepasa la posición final especificada con una línea vertical recta en el lado exterior. El punto final interno parece estar bien. Por supuesto esto y el otro desorden de líneas no dice qué causa el problema.

Parece que aparece cuando el ángulo final es exactamente un múltiplo de 90 grados. Esto se parece a un error de cálculo numérico, un problema de redondeo de flotación, etc. @kcoppock comentó que 314.98f ya elude el error. Probablemente cualquier valor que no sea exactamente 315.0f puede hacer el truco.

Si la optimización del código está involucrada (intenta dibujar el arco en segmentos de línea lo más pequeños posible) otro truco que puede funcionar es simplificar el arco cortándolo en pedazos -> utilizar varias llamadas drawArc que cada uno abarcan un determinado ángulo máximo. Los candidatos son 30, 45, 90 y 180 grados. Queda por verse si las articulaciones serán invisibles …

Es un poco un tiro largo, espero que cualquiera de estas sugerencias podría funcionar.

¡He encontrado la solución! 🙂

En lugar de esto:

 RectF rectangle = new RectF(60f, 60f, 480f, 480f); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(0x40000000); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(120); canvas.drawArc(rectangle, 225f, 315f, false, paint); 

Utilizar esta:

 RectF rectangle = new RectF(60f, 60f, 480f, 480f); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(0x40000000); paint.setStyle(Paint.Style.FILL); float strokeWidth = 120; float startAngle = 225f; float sweepAngle = 315f; RectF pathRect = new RectF(); Path path = new Path(); float s = strokeWidth / 2; pathRect.left = rectangle.left - s; pathRect.right = rectangle.right + s; pathRect.top = rectangle.top - s; pathRect.bottom = rectangle.bottom + s; path.arcTo(pathRect, startAngle, sweepAngle); pathRect.left = rectangle.left + s; pathRect.right = rectangle.right - s; pathRect.top = rectangle.top + s; pathRect.bottom = rectangle.bottom - s; path.arcTo(pathRect, startAngle + sweepAngle, -sweepAngle); path.close(); canvas.drawPath(path, paint); 

Este código produce una ejecución más lenta, pero no produce artefactos. 🙂

  • Vista personalizada CustomView no utiliza los constructores de vista de 2 o 3 argumentos
  • Android dibujar círculo con 2 colores (gráfico circular)
  • Restaurar estado de vista antes de aplicar atributos XML
  • Desliza para elegir Android
  • Establecer valor de enum en xml del recurso
  • Cómo fijar la aplicación no responde?
  • Botones circulares Vista de grupo
  • Android AlertDialog reglas setView
  • Mapa de bits no dibujado anti-alias
  • ¿Necesito los tres constructores para una vista personalizada de Android?
  • Aplicar como listview
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.