Compose Component

RangeSlider

Material Design range slider Range Sliders expand upon Slider using the same concepts but allow the user to select 2 values.

RangeSlider social preview

RangeSliderSample

@Preview
@Sampled
@Composable
fun RangeSliderSample() {
    val rangeSliderState = rememberRangeSliderState(0f, 100f, trackRange = 0f..100f)
    Column(modifier = Modifier.padding(horizontal = 16.dp)) {
        val rangeStart = "%.2f".format(rangeSliderState.startValue)
        val rangeEnd = "%.2f".format(rangeSliderState.endValue)
        Text(text = "$rangeStart .. $rangeEnd")
        RangeSlider(
            state = rangeSliderState,
            onValueChange = {
                rangeSliderState.startValue = it.start
                rangeSliderState.endValue = it.endInclusive
            },
            onValueChangeFinished = {
                // launch some business logic update with the state you hold
                // viewModel.updateSelectedSliderValue(sliderPosition)
            },
        )
    }
}

StepRangeSliderSample

@Preview
@Sampled
@Composable
fun StepRangeSliderSample() {
    val rangeSliderState =
        rememberRangeSliderState(
            0f,
            100f,
            trackRange = 0f..100f,
            // Only allow multiples of 10. Excluding the endpoints of `valueRange`,
            // there are 9 steps (10, 20, ..., 90).
            steps = 9,
        )
    Column(modifier = Modifier.padding(horizontal = 16.dp)) {
        val rangeStart = rangeSliderState.startValue.roundToInt()
        val rangeEnd = rangeSliderState.endValue.roundToInt()
        Text(text = "$rangeStart .. $rangeEnd")
        RangeSlider(
            state = rangeSliderState,
            onValueChange = {
                rangeSliderState.startValue = it.start
                rangeSliderState.endValue = it.endInclusive
            },
            onValueChangeFinished = {
                // launch some business logic update with the state you hold
                // viewModel.updateSelectedSliderValue(sliderPosition)
            },
        )
    }
}

RangeSliderWithCustomComponents

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Sampled
@Composable
fun RangeSliderWithCustomComponents() {
    val rangeSliderState = rememberRangeSliderState(0f, 100f, trackRange = 0f..100f)
    val startInteractionSource = remember { MutableInteractionSource() }
    val endInteractionSource = remember { MutableInteractionSource() }
    val startThumbAndTrackColors =
        SliderDefaults.colors(thumbColor = Color.Blue, activeTrackColor = Color.Red)
    val endThumbColors = SliderDefaults.colors(thumbColor = Color.Green)
    Column(modifier = Modifier.padding(horizontal = 16.dp)) {
        RangeSlider(
            state = rangeSliderState,
            onValueChange = {
                rangeSliderState.startValue = it.start
                rangeSliderState.endValue = it.endInclusive
            },
            startThumbInteractionSource = startInteractionSource,
            endThumbInteractionSource = endInteractionSource,
            onValueChangeFinished = {
                // launch some business logic update with the state you hold
                // viewModel.updateSelectedSliderValue(sliderPosition)
            },
            startThumb = {
                Label(
                    label = {
                        PlainTooltip(modifier = Modifier.sizeIn(45.dp, 25.dp).wrapContentWidth()) {
                            Text("%.2f".format(rangeSliderState.startValue))
                        }
                    },
                    interactionSource = startInteractionSource,
                ) {
                    SliderDefaults.Thumb(
                        interactionSource = startInteractionSource,
                        colors = startThumbAndTrackColors,
                    )
                }
            },
            endThumb = {
                Label(
                    label = {
                        PlainTooltip(
                            modifier = Modifier.requiredSize(45.dp, 25.dp).wrapContentWidth()
                        ) {
                            Text("%.2f".format(rangeSliderState.endValue))
                        }
                    },
                    interactionSource = endInteractionSource,
                ) {
                    SliderDefaults.Thumb(
                        interactionSource = endInteractionSource,
                        colors = endThumbColors,
                    )
                }
            },
            track = { rangeSliderState ->
                SliderDefaults.Track(
                    colors = startThumbAndTrackColors,
                    rangeSliderState = rangeSliderState,
                )
            },
        )
    }
}

Content updated: