Currently I'm trying to find an easy way to implement a step progress bar with compose like this:
Does anyone have experience with that? Is there maybe a good library?
Currently I'm trying to find an easy way to implement a step progress bar with compose like this:
Does anyone have experience with that? Is there maybe a good library?
I don't think you need a library from this one, a simple and quick 'do it yourself' solution could be something like this:
@Composable
fun StepsProgressBar(modifier: Modifier = Modifier, numberOfSteps: Int, currentStep: Int) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically
) {
for (step in 0..numberOfSteps) {
Step(
modifier = Modifier.weight(1F),
isCompete = step < currentStep,
isCurrent = step == currentStep
)
}
}
}
@Composable
fun Step(modifier: Modifier = Modifier, isCompete: Boolean, isCurrent: Boolean) {
val color = if (isCompete || isCurrent) Color.Red else Color.LightGray
val innerCircleColor = if (isCompete) Color.Red else Color.LightGray
Box(modifier = modifier) {
//Line
Divider(
modifier = Modifier.align(Alignment.CenterStart),
color = color,
thickness = 2.dp
)
//Circle
Canvas(modifier = Modifier
.size(15.dp)
.align(Alignment.CenterEnd)
.border(
shape = CircleShape,
width = 2.dp,
color = color
),
onDraw = {
drawCircle(color = innerCircleColor)
}
)
}
}
@Preview
@Composable
fun StepsProgressBarPreview() {
val currentStep = remember { mutableStateOf(1) }
StepsProgressBar(modifier = Modifier.fillMaxWidth(), numberOfSteps = 5, currentStep = currentStep.value)
}
This will be the result:
I have created a similar function that takes customisable params.
@Composable
fun Track(
items: Int,
brush: (from: Int) -> Brush,
modifier: Modifier = Modifier,
lineWidth: Dp = 1.dp,
pathEffect: ((from: Int) -> PathEffect?)? = null,
icon: @Composable (index: Int) -> Unit,
) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
Canvas(
modifier = Modifier
.fillMaxWidth()
.zIndex(-1f)
) {
val width = drawContext.size.width
val height = drawContext.size.height
val yOffset = height / 2
val itemWidth = width / items
var startOffset = itemWidth / 2
var endOffset = startOffset
val barWidth = lineWidth.toPx()
repeat(items - 1) {
endOffset += itemWidth
drawLine(
brush = brush.invoke(it),
start = Offset(startOffset, yOffset),
end = Offset(endOffset, yOffset),
strokeWidth = barWidth,
pathEffect = pathEffect?.invoke(it)
)
startOffset = endOffset
}
}
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically,
) {
repeat(items) { index ->
Box(
contentAlignment = Alignment.Center,
) {
icon.invoke(index)
}
}
}
}
}
Add jitpack in your build.gradle:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add compose-stepper library to your app/build.gradle
dependencies {
implementation 'com.github.maryamrzdh:compose-stepper:1.0.0-beta01'
}
Add a Stepper in a composable function
@Composable
fun StepperView() {
val numberOfSteps = 4
var currentStep by rememberSaveable { mutableStateOf(1) }
val titleList= arrayListOf("Step 1","Step 2","Step 3","Step 4")
Stepper(
modifier = Modifier.fillMaxWidth(),
numberOfSteps = numberOfSteps,
currentStep = currentStep,
stepDescriptionList = titleList,
unSelectedColor= Color.LightGray,
selectedColor = Color.Blue,
isRainbow = false
)
For more info go to Stepper using JetPack Compose