I want to make a shape filling the circle according to given percentage. Since i suck at math I'm unable to achieve this with path Api of jetpack compose.
My custom class is looking like this:
class ProgressPie(val progress: Float) : Shape {
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline {
val path = Path().apply {
addArc(
Rect(0f, 0f, size.width , size.height ),
-90f,
360f * progress
)
close()
}
return Outline.Generic(path)
}
}
and when the progress parameter changed the result should be looking like this.
CodePudding user response:
You can use Canvas or Modifier.draWithContent
to draw a pie chart.
Column(modifier=Modifier.padding(10.dp)) {
var progress by remember { mutableStateOf(0f) }
Box(
modifier = Modifier
.background(Color.White)
.fillMaxWidth()
.aspectRatio(1f)
.drawBehind {
drawCircle(Color.LightGray, style = Stroke(1.dp.toPx()))
drawArc(
Color.Blue,
startAngle = -90f,
sweepAngle = progress,
useCenter = true
)
}
)
Slider(
value = progress,
onValueChange = {
progress = it
},
valueRange = 0f..360f
)
}
You can use shape with remember to create new shape on progress change but the issue with Path and arc is it's not drawn from center.
val shape = remember(progress) {
GenericShape { size: Size, _: LayoutDirection ->
if( progress == 360f){
addOval(
Rect(0f, 0f, size.width, size.height)
)
}else {
moveTo(size.width/2f, size.height/2f)
arcTo(
Rect(0f, 0f, size.width, size.height),
-90f,
progress,
forceMoveTo = false
)
}
close()
}
}
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.White)
.clip(shape)
.background(Color.Blue)
.aspectRatio(1f)
)