I’m trying to create a custom progress bar in Jetpack Compose, where each step is represented by a dot, and beneath each dot, there’s a text label. However, I’m having trouble aligning the text labels so that they are properly centerred under each dot.
This is what i’m trying to achieve:
Here is my current implementation:
@Composable
fun StepsProgressView(
steps: List<IdentificationStep>,
modifier: Modifier = Modifier,
lineWidth: Dp = 1.dp,
completedIndex: Int = 2
) {
Column(modifier = modifier) {
Box(contentAlignment = Alignment.Center) {
Canvas(modifier = Modifier.fillMaxWidth()) {
val width = drawContext.size.width
val height = drawContext.size.height
val yOffset = height / 2
val itemWidth = width / steps.size
var startOffset = itemWidth / 2
var endOffset = startOffset
val barWidth = lineWidth.toPx()
repeat(steps.size - 1) { index ->
endOffset += itemWidth
if (index < 3)
endOffset -= 6
drawLine(
brush = SolidColor(if (index < completedIndex) primaryColor else grayDividerColor),
start = Offset(startOffset, yOffset),
end = Offset(endOffset, yOffset),
strokeWidth = barWidth
)
startOffset = endOffset
}
}
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically,
) {
repeat(steps.size) { index ->
Box(contentAlignment = Alignment.Center) {
// last index image
if (index == steps.lastIndex)
Image(
painter = painterResource(id = R.drawable.barImage),
contentDescription = null,
modifier = Modifier.size(24.dp),
contentScale = ContentScale.Crop
)
// circles box
else
Box(
modifier = Modifier
.size(12.dp)
.drawBehind {
drawCircle(
color =
if (index <= completedIndex) primaryColor
else grayDividerColor
)
},
contentAlignment = Alignment.Center,
content = {})
}
}
}
}
Spacer(Modifier.height(8.dp))
Row(
Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceAround
) {
steps.forEachIndexed { index, step ->
HelpText(
text = step.getTitleForProgressbar(),
fontSize = 13,
modifier = Modifier.wrapContentWidth().weight(1f),
color = if (steps.indexOf(step) <= completedIndex) primaryColor else secondaryColor,
textAlign = TextAlign.Center
)
}
}
}
}
The issue I’m facing is that the text labels beneath the dots are not perfectly aligned in the center. I want each text label to be directly centered below its corresponding dot.
Any suggestions would be highly appreciated. Thank you!