Android: disegna un arco all'interno dell'API della tela con un colore di riempimento sfumato
-
27-10-2019 - |
Domanda
Voglio disegnare un arco usando la tela usando un riempimento sfumato.Come si può ottenere questo risultato?
Soluzione
Ehi, l'ho rubato da qui: Disegna un arco con SweepGradientin Android
ma funziona bene, ho usato invece un LinearGradient.
Shader gradient = new SweepGradient (0,getMeasuredHeight()/2, Color.RED, Color.WHITE);
lightRed.setShader(gradient);
canvas.drawArc(rectf, -90, 360, false, lightRed);
Altri suggerimenti
Per la mia causa ho dovuto disegnare qualcuno come questo:
Forse anche tu.
Quindi, pensiamo! Come funziona Sweep Gradient? Se disegni rect tramite questo:
private val colors = intArrayOf(ContextCompat.getColor(context, R.color.progress_from_color),
ContextCompat.getColor(context, R.color.progress_to_color))
private var positions = floatArrayOf(0.0f, 1.0f)
private var sweepGradient : SweepGradient? = null
sweepGradient = SweepGradient(w / 2F,h / 2F,colors, positions)
sarà:
Quindi l'idea è di ruotarlo!
sweepGradient.apply {
val rotate = 270f
val gradientMatrix = Matrix()
gradientMatrix.preRotate(rotate, mWidth / 2F, mHeight / 2F)
setLocalMatrix(gradientMatrix)
}
Finalmente possiamo disegnare il nostro arco:
mPaint.shader = gradient
canvas.drawArc(rectF, startAngle, finishedSweepAngle, false, mPaint)
Visualizza il mio codice sorgente della visualizzazione personalizzata su github repository .
Puoi anche utilizzare una serie di colori e posizioni variabili. Ad esempio, definisci 10 colori, uno ogni 10% di avanzamento:
<color name="color_0">#3C3C3F41</color>
<color name="color_10">#1AFF2323</color>
<color name="color_20">#33FF2323</color>
<color name="color_30">#4DFF2323</color>
<color name="color_40">#66FF2323</color>
<color name="color_50">#80FF2323</color>
<color name="color_60">#99FF2323</color>
<color name="color_70">#B3FF2323</color>
<color name="color_80">#CCFF2323</color>
<color name="color_90">#E6FF2323</color>
<color name="color_100">#FFFF2323</color>
Metti tutti questi colori all'interno di un intArray di colori come questo:
var colors = intArrayOf(
ContextCompat.getColor(context, R.color.color_0),
ContextCompat.getColor(context, R.color.color_10),
ContextCompat.getColor(context, R.color.color_20),
ContextCompat.getColor(context, R.color.color_30),
ContextCompat.getColor(context, R.color.color_40),
ContextCompat.getColor(context, R.color.color_50),
ContextCompat.getColor(context, R.color.color_60),
ContextCompat.getColor(context, R.color.color_70),
ContextCompat.getColor(context, R.color.color_80),
ContextCompat.getColor(context, R.color.color_90),
ContextCompat.getColor(context, R.color.color_100)
)
Quindi, definisci le posizioni.Sweep delle posizioni da 0,0 a 1,0 (le posizioni 0,1 corrispondono a color_10, la posizione 0,2 a color_20 ecc.)
var positions = floatArrayOf(0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f)
Una volta definite le posizioni, possiamo impostare SweepGradient sulla nostra vernice
Shader gradient = new SweepGradient (0,getMeasuredHeight()/2, colors, positions);
lightRed.setShader(gradient);
Finalmente possiamo disegnare il nostro arco con la nostra pittura shader:
canvas.drawArc(rectf, -90, 360, false, lightRed);
Effetto finale nella mia visualizzazione personalizzata: