Search code examples
androidkotlinuser-interfaceandroid-jetpack-compose

Sweep gradient circular progress bar in jetpack compose


I want to create a circular progress bar with a gradient like this using jetpack compose

sweepGradient circular progress bar

I tried to do it using the Brush.sweepGradient however, it didn't work correctly as the start angle of the progress bar and the sweep Gradient aren't the same, and there is not parameter to control the angle in the sweepGradient How to do it??


Solution

  • I don't think it's possible to give a gradient color to CircularProgressIndicator because as of now its color parameter only accepts the Color type and I don't see any overload with the Brush type for its color.

    One way to achieve what you want is to draw a ring using Canvas, however, a simple ring is not enough. With some tweaks, you can achieve this:

    gradient progress bar

    @Composable
    fun GradientProgress(
        modifier: Modifier = Modifier,
        diameter: Dp = 100.dp,
        width: Float = 10f,
        colors: List<Color> = listOf(Color.Cyan, Color.Blue),
        progress: Float = .75f
    ) {
        Box(
            content = {
                Text(
                    text = "${(progress * 100).toInt()}",
                    modifier = Modifier.align(Alignment.Center)
                )
                Canvas(
                    modifier = modifier
                        .size(diameter)
                        .rotate(-90f)
                        .graphicsLayer {
                            rotationY = 360f
                        },
                    onDraw = {
                        drawArc(
                            color = Color.LightGray,
                            startAngle = 0f,
                            sweepAngle = 360f,
                            false,
                            style = Stroke(width = width)
                        )
                        drawArc(
                            brush = Brush.sweepGradient(colors = colors),
                            startAngle = 0f,
                            sweepAngle = progress * 360f,
                            false,
                            style = Stroke(width = width)
                        )
                    }
                )
            }
        )
    }