Stepper
Component in Wear Material 3 Compose
[Stepper] allows users to make a selection from a range of values. It's a full-screen control with increase button on the top, decrease button on the bottom and a slot (expected to have either [Text] or [Button]) in the middle. Value can be increased and decreased by clicking on the increase and decrease buttons. Buttons can have custom icons - [decreaseIcon] and [increaseIcon]. Step value is calculated as the difference between min and max values divided by [steps]+1. Stepper itself doesn't show the current value but can be displayed via the content slot or [LevelIndicator] if required. If [value] is not equal to any step value, then it will be coerced to the closest step value. However, the [value] itself will not be changed and [onValueChange] in this case will not be triggered. To add range semantics on Stepper, use [Modifier.rangeSemantics].
Last updated:
Installation
dependencies {
implementation("androidx.wear.compose:compose-material3:1.0.0-alpha27")
}
Overloads
@Composable
fun Stepper(
value: Float,
onValueChange: (Float) -> Unit,
steps: Int,
modifier: Modifier = Modifier,
decreaseIcon: @Composable () -> Unit = StepperDefaults.DecreaseIcon,
increaseIcon: @Composable () -> Unit = StepperDefaults.IncreaseIcon,
enabled: Boolean = true,
valueRange: ClosedFloatingPointRange<Float> = 0f..(steps + 1).toFloat(),
colors: StepperColors = StepperDefaults.colors(),
content: @Composable BoxScope.() -> Unit
)
Parameters
name | description |
---|---|
value | Current value of the Stepper. If outside of [valueRange] provided, value will be coerced to this range. |
onValueChange | Lambda in which value should be updated. |
steps | Specifies the number of discrete values, excluding min and max values, evenly distributed across the whole value range. Must not be negative. If 0, stepper will have only min and max values and no steps in between. |
modifier | Modifiers for the Stepper layout. |
decreaseIcon | A slot for an icon which is placed on the decrease (bottom) button. |
increaseIcon | A slot for an icon which is placed on the increase (top) button. |
enabled | Whether the [Stepper] is enabled. |
valueRange | Range of values that Stepper value can take. Passed [value] will be coerced to this range. |
colors | [StepperColors] that will be used to resolve the colors used for this [Stepper]. See [StepperDefaults.colors]. |
content | Content body for the Stepper. |
@Composable
fun Stepper(
value: Int,
onValueChange: (Int) -> Unit,
valueProgression: IntProgression,
modifier: Modifier = Modifier,
decreaseIcon: @Composable () -> Unit = StepperDefaults.DecreaseIcon,
increaseIcon: @Composable () -> Unit = StepperDefaults.IncreaseIcon,
enabled: Boolean = true,
colors: StepperColors = StepperDefaults.colors(),
content: @Composable BoxScope.() -> Unit
)
Parameters
name | description |
---|---|
value | Current value of the Stepper. If outside of [valueProgression] provided, value will be coerced to this range. |
onValueChange | Lambda in which value should be updated. |
valueProgression | Progression of values that Stepper value can take. Consists of rangeStart, rangeEnd and step. Range will be equally divided by step size. |
modifier | Modifiers for the Stepper layout. |
decreaseIcon | A slot for an icon which is placed on the decrease (bottom) button. |
increaseIcon | A slot for an icon which is placed on the increase (top) button. |
enabled | Whether the [Stepper] is enabled. |
colors | [StepperColors] that will be used to resolve the colors used for this [Stepper]. See [StepperDefaults.colors]. |
content | Content body for the Stepper. |
Code Examples
StepperSample
@Composable
fun StepperSample() {
var value by remember { mutableFloatStateOf(2f) }
val valueRange = 0f..4f
Box(modifier = Modifier.fillMaxSize()) {
Stepper(value = value, onValueChange = { value = it }, valueRange = valueRange, steps = 7) {
Text(String.format("Value: %.1f".format(value)))
}
LevelIndicator(
value = { value },
valueRange = valueRange,
modifier = Modifier.align(Alignment.CenterStart)
)
}
}
StepperWithRangeSemanticsSample
@Composable
fun StepperWithRangeSemanticsSample() {
var value by remember { mutableFloatStateOf(2f) }
val valueRange = 0f..4f
val onValueChange = { i: Float -> value = i }
val steps = 7
Box(modifier = Modifier.fillMaxSize()) {
Stepper(
value = value,
onValueChange = onValueChange,
valueRange = valueRange,
modifier = Modifier.rangeSemantics(value, true, onValueChange, valueRange, steps),
steps = steps,
) {
Text("Value: $value")
}
LevelIndicator(
value = { value },
valueRange = valueRange,
modifier = Modifier.align(Alignment.CenterStart)
)
}
}
StepperWithButtonSample
@Composable
fun StepperWithButtonSample() {
var value by remember { mutableFloatStateOf(2f) }
val valueRange = 0f..4f
Box(modifier = Modifier.fillMaxSize()) {
Stepper(
value = value,
onValueChange = { value = it },
valueRange = valueRange,
increaseIcon = { VolumeUpIcon(24.dp) },
decreaseIcon = { VolumeDownIcon(24.dp) },
steps = 7
) {
Text(String.format("Value: %.1f".format(value)))
Button(
onClick = {},
modifier = Modifier.width(150.dp),
label = { Text(text = "This watch", modifier = Modifier.fillMaxWidth()) },
secondaryLabel = { Text(text = "Headphones", modifier = Modifier.fillMaxWidth()) },
icon = { HeadphoneIcon(24.dp) },
)
}
LevelIndicator(
value = { value },
valueRange = valueRange,
modifier = Modifier.align(Alignment.CenterStart)
)
}
}
StepperWithIntegerSample
@Composable
fun StepperWithIntegerSample() {
var value by remember { mutableIntStateOf(3) }
val valueProgression = 0..10
Box(modifier = Modifier.fillMaxSize()) {
Stepper(
value = value,
onValueChange = { value = it },
valueProgression = valueProgression
) {
Text(String.format("Value: %d".format(value)))
}
LevelIndicator(
value = { value },
valueProgression = valueProgression,
modifier = Modifier.align(Alignment.CenterStart)
)
}
}