Question

I want to draw an arc using canvas using a gradient fill. How can achieve this?

Was it helpful?

Solution

Hey I stole this from here: Draw an arc with a SweepGradient in Android

but it works fine, I used a LinearGradient instead.

Shader gradient = new SweepGradient (0,getMeasuredHeight()/2, Color.RED, Color.WHITE);
lightRed.setShader(gradient);
canvas.drawArc(rectf, -90, 360, false, lightRed);

OTHER TIPS

In my cause i I had to draw someone like this:

Maybe you too.

So, let's think! How does Sweep Gradient works? If you draw rect via this:

     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)

will be:

So the idea is to rotate it!

 sweepGradient.apply {
            val rotate = 270f
            val gradientMatrix = Matrix()
            gradientMatrix.preRotate(rotate, mWidth / 2F, mHeight / 2F)
            setLocalMatrix(gradientMatrix)
        }

Finally we can draw our arc:

 mPaint.shader = gradient
 canvas.drawArc(rectF, startAngle, finishedSweepAngle, false, mPaint)

See my full custom view source code on github repository.

You can also use an array of colors and variable positions. For example, define 10 colors, one each 10% progress:

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

Put all of these colors inside a colors intArray like this:

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

Then, define positions. Positions sweep from 0.0 to 1.0 (positions 0.1 corresponds to color_10, position 0.2 to color_20 etc.)

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)

Once we've defined positions, we can set the SweepGradient to our paint

Shader gradient = new SweepGradient (0,getMeasuredHeight()/2, colors, positions);
lightRed.setShader(gradient);

Finally we can draw our arc with our shader paint:

 canvas.drawArc(rectf, -90, 360, false, lightRed);

Final effect in my custom view:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top