I am trying to show progress using drawArc
for compose. I have tried drawBehind
modifier to draw a background circle and not trying to draw another circle on top of it to show the progress. The problems is, no matter what I try, the arc turns out to be drawn at top left corner all the time. If I explicitly define the topLeft
value, it only works for 1 screen size. So I am trying to get a dynamic size for both circles and also the strokewidth. So for Tablets only the circles should be increased depending on the screensize and also the thickness should be increased for the same. And for the smaller size devices, the value should be decreasing. Here is my code and output:
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
BoxWithConstraints(
Modifier
.fillMaxSize()
.background(Color.Yellow),
) {
Canvas(modifier = Modifier
.size(maxWidth, maxHeight)
.background(color = Color.Red)) {
drawCircle(
color = Color.Gray,
radius = (maxWidth /4).toPx(),
style = Stroke(width = 14f, cap = StrokeCap.Round),
)
val sweepAngle = progress/100 * 360
drawArc(
size = Size((maxWidth/2).toPx(),(maxWidth/2).toPx()),
color = Color.Green,
startAngle = -90f,
sweepAngle = sweepAngle,
useCenter = false,
style = Stroke(10f, cap = StrokeCap.Round),
)
}
}
}
PS: I cannot use another circle object since I need to have the tip of the circle round aka cap should be Stroke.Round.
I ended up trying BoxWithConstraints
so I can have access to maxWidth
and maxHeight
You have to calculate the topLeft offset of the arc as center of the circle - radius of the circle
.
Then the size of arc is maxWidth/2
instead of maxWidth/4 = radius
.
Something like:
val stroke = 5.dp
drawCircle(
color = Color.Gray,
radius = (maxWidth /4).toPx(),
style = Stroke(width = stroke.toPx(), cap = StrokeCap.Round),
)
val sweepAngle = progress/100 * 360
val offsetx = this.center.x - (maxWidth/4).toPx()
val offsety = this.center.y - (maxWidth/4).toPx()
drawArc(
size = Size((maxWidth/2).toPx(),(maxWidth/2).toPx()),
color = Color.Green,
startAngle = 0f,
sweepAngle = -sweepAngle,
topLeft = Offset(offsetx,offsety),
useCenter = false,
style = Stroke(stroke.toPx(), cap = StrokeCap.Round),
)
}