studio sketchbook programacion móviles libros dibujar desarrollo desarrollar curso como aprende aplicaciones android graphics 2d geometric-arc

sketchbook - manual de programacion android pdf



Android-Cómo dibujar un gradiente basado en arco (3)

Cinco años después, pero la forma correcta es hacer 0.749f con 0.750f de la línea separada, el código simple es como:

val colors = intArrayOf(0xffff0000.toInt(), 0xff0000ff.toInt(), 0xffff0000.toInt(), 0xffff0000.toInt()) val positions = floatArrayOf(0.0f, 0.749f, 0.750f, 1.0f)

Estoy tratando de crear un arco (número variable de grados) que gradualmente va de un color a otro. Del ejemplo del azul al rojo:

Este es mi código:

SweepGradient shader = new SweepGradient(center.x, center.y, resources.getColor(R.color.startColor),resources.getColor(R.color.endColor)); Paint paint = new Paint() paint.setStrokeWidth(1); paint.setStrokeCap(Paint.Cap.FILL); paint.setStyle(Paint.Style.FILL); paint.setShader(shader); canvas.drawArc(rectF, startAngle, sweepAngle, true, paint);

Pero el resultado es que todo el arco está pintado con el mismo color.

Editar:
Después de experimentar más, descubrí que la extensión del color está determinada por el ángulo del arco. Si dibujo un arco con un ángulo pequeño, solo se muestra el primer color. Cuanto mayor sea el ángulo, más colores se dibujan. Si el ángulo es pequeño parece que no hay gradiente.
Aquí hay un ejemplo. Estoy dibujando 4 arcos - 90, 180, 270 y 360:

RectF rect1 = new RectF(50, 50, 150, 150); Paint paint1 = new Paint(); paint1.setStrokeWidth(1); paint1.setStrokeCap(Paint.Cap.SQUARE); paint1.setStyle(Paint.Style.FILL); SweepGradient gradient1 = new SweepGradient(100, 100, Color.RED, Color.BLUE); paint1.setShader(gradient1); canvas.drawArc(rect1, 0, 90, true, paint1); RectF rect2 = new RectF(200, 50, 300, 150); Paint paint2 = new Paint(); paint2.setStrokeWidth(1); paint2.setStrokeCap(Paint.Cap.SQUARE); paint2.setStyle(Paint.Style.FILL); SweepGradient gradient2 = new SweepGradient(250, 100, Color.RED, Color.BLUE); paint2.setShader(gradient2); canvas.drawArc(rect2, 0, 180, true, paint2); RectF rect3 = new RectF(50, 200, 150, 300); Paint paint3 = new Paint(); paint3.setStrokeWidth(1); paint3.setStrokeCap(Paint.Cap.SQUARE); paint3.setStyle(Paint.Style.FILL); SweepGradient gradient3 = new SweepGradient(100, 250, Color.RED, Color.BLUE); paint3.setShader(gradient3); canvas.drawArc(rect3, 0, 270, true, paint3); RectF rect4 = new RectF(200, 200, 300, 300); Paint paint4 = new Paint(); paint4.setStrokeWidth(1); paint4.setStrokeCap(Paint.Cap.SQUARE); paint4.setStyle(Paint.Style.FILL); SweepGradient gradient4 = new SweepGradient(250, 250, Color.RED, Color.BLUE); paint4.setShader(gradient4); canvas.drawArc(rect4, 0, 360, true, paint4);

Y aqui esta el resultado:

Esto es sorprendente porque esperaría que el ROJO estuviera al comienzo del arco, que el AZUL al final y todo se distribuyera uniformemente independientemente del ángulo.
Intenté espaciar los colores manualmente usando el parámetro posiciones, pero los resultados fueron los mismos:

int[] colors = {Color.RED, Color.BLUE}; float[] positions = {0,1}; SweepGradient gradient = new SweepGradient(100, 100, colors , positions);

Alguna idea de como resolver esto?


La solución para esto es establecer la posición de AZUL. Esto se hace así:

int[] colors = {Color.RED, Color.BLUE}; float[] positions = {0,1}; SweepGradient gradient = new SweepGradient(100, 100, colors , positions);

El problema aquí es que al establecer la posición de AZUL en ''1'' esto no significa que se posicionará al final del arco dibujado, sino al final del círculo del cual forma parte el arco. Para resolver esto, la posición AZUL debe tener en cuenta el número de grados en el arco. Entonces, si estoy dibujando un arco con X grados, la posición se establecerá así:

float[] positions = {0,Xf/360f};

Entonces, si X es 90, el gradiente colocará AZUL en 0.25 del círculo:


Para agregar a la solución de Yoav.

En mi Android Galaxy Nexus 4.2, la solución dada no funciona.

Si la matriz no contiene 0.0f y 1.0f, parece que se ignora.

Mi solución final fue:

int[] colors = {Color.RED, Color.BLUE, Color.RED}; float[] positions = {0, Xf/360f, 1};