Sliders allow users to make selections from a range of values.
Before you can use Material sliders, you need to add a dependency to the Material Components for Android library. For more information, go to the Getting started page.
A Slider can be added in a layout like so:
<!-- Continuous slider -->
<com.google.android.material.slider.Slider
...
android:valueFrom="0.0"
android:valueTo="100.0" />
<!-- Discrete slider -->
<com.google.android.material.slider.Slider
...
android:valueFrom="0.0"
android:valueTo="100.0"
android:stepSize="10.0" />Changes to a slider can be observed like so:
slider.addOnSliderTouchListener(object : Slider.OnSliderTouchListener {
override fun onStartTrackingTouch(slider: Slider) {
// Responds to when slider's touch event is being started
}
override fun onStopTrackingTouch(slider: Slider) {
// Responds to when slider's touch event is being stopped
}
})
slider.addOnChangeListener { slider, value, fromUser ->
// Responds to when slider's value is changed
}Similarly, a RangeSlider can be added in a layout like so:
<!-- Continuous slider -->
<com.google.android.material.slider.RangeSlider
...
android:valueFrom="0.0"
android:valueTo="100.0"
app:values="@array/initial_values" />
<!-- Discrete slider -->
<com.google.android.material.slider.RangeSlider
...
android:valueFrom="0.0"
android:valueTo="100.0"
app:values="@array/initial_slider_values"
android:stepSize="10.0" />And in values/arrays.xml:
<resources>
<array name="initial_slider_values">
<item>20.0</item>
<item>70.0</item>
</array>
</resources>Changes to a range slider can be observed like so:
rangeSlider.addOnSliderTouchListener(object : RangeSlider.OnSliderTouchListener {
override fun onStartTrackingTouch(slider: RangeSlider) {
// Responds to when slider's touch event is being started
}
override fun onStopTrackingTouch(slider: RangeSlider) {
// Responds to when slider's touch event is being stopped
}
})
rangeSlider.addOnChangeListener { rangeSlider, value, fromUser ->
// Responds to when slider's value is changed
}Sliders support setting content descriptors for use with screen readers. While optional, we strongly encourage their use.
That can be done in XML via the android:contentDescription attribute or
programmatically like so:
slider.contentDescription = contentDescriptionAdditionaly, if using a TextView to display the value of the slider, you
should set android:labelFor on it, so that screen readers announce that
TextView refers to the slider.
By default, the slider will show a value label above the thumb when it's
selected. You can change how it's drawn via the app:labelBehavior attribute or
setLabelBehavior method.
The modes of app:labelBehavior are:
floating(default) - draws the label floating above the bounds of this viewwithinBounds- draws the label floating within the bounds of this viewgone- prevents the label from being drawn
By using a LabelFormatter you can display the selected value using letters to
indicate magnitude (e.g.: 1.5K, 3M, 12B). That can be achieved through the
setLabelFormatter method.
The following example shows a slider for a prince range in the USD currency.
In code:
rangeSlider.setLabelFormatter { value: Float ->
val format = NumberFormat.getCurrencyInstance()
format.maximumFractionDigits = 0
format.currency = Currency.getInstance("USD")
format.format(value.toDouble())
}There are two types of sliders: 1. Continuous slider, 2. Discrete slider
A slider with two thumbs is called a range slider.
Continuous sliders allow users to make meaningful selections that don’t require a specific value.
API and source code:
Slider
The following example shows a continuous slider.
In the layout:
<com.google.android.material.slider.Slider
android:id="@+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/slider_desc"
android:value="20.0"
android:valueFrom="0.0"
android:valueTo="100.0" />API and source code:
RangeSlider
The following example shows a continuous range slider.
In the layout:
<com.google.android.material.slider.RangeSlider
android:id="@+id/range_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/slider_desc"
app:values="@array/initial_slider_values"
android:valueFrom="0.0"
android:valueTo="100.0" />Discrete sliders display a numeric value label upon pressing the thumb, which allows a user to input an exact value.
API and source code:
Slider
The following example shows a discrete slider.
In the layout:
<com.google.android.material.slider.Slider
...
android:stepSize="5.0" />API and source code:
RangeSlider
The following example shows a discrete range slider.
In the layout:
<com.google.android.material.slider.RangeSlider
...
android:stepSize="5.0" />A slider has a track, one or two thumbs, and optional value label. A discrete slider also has tick marks.
- Track
- Thumb
- Value label (optional)
- Tick mark (discrete sliders)
| Attribute | Related method(s) | Default value | |
|---|---|---|---|
| Min value | android:valueFrom |
setValueFromgetValueFrom |
N/A |
| Max value | android:valueTo |
setValueTogetValueTo |
N/A |
| Step size (discrete) | android:stepSize |
setStepSizegetStepSize |
N/A |
| Initial selected value (Slider) | android:value |
setValuegetValue |
N/A |
| Initial selected values (RangeSlider) | app:values |
setValuesgetValues |
N/A |
| Height | app:trackHeight |
setTrackHeightgetTrackHeight |
4dp |
| Color | app:trackColor |
setTrackTintListgetTrackTintList |
null |
| Color for track's active part | app:trackColorActive |
setTrackActiveTintListgetTrackActiveTintList |
?attr/colorPrimary |
| Color for track's inactive part | app:trackColorInactive |
setTrackInactiveTintListgetTrackInactiveTintList |
?attr/colorPrimary at 24% |
| Minimum separation for adjacent thumbs | app:minSeparation |
setMinSeparationgetMinSeparation |
0dp |
Note: app:trackColor takes precedence over app:trackColorActive and
app:trackColorInative. It's a shorthand for setting both values to the same
thing.
| Attribute | Related method(s) | Default value | |
|---|---|---|---|
| Color | app:thumbColor |
setThumbTintListgetThumbTintList |
?attr/colorPrimary |
| Radius | app:thumbRadius |
setThumbRadiusResourcesetThumbRadiusgetThumbRadius |
10dp |
| Elevation | app:thumbElevation |
setThumbElevationResourcesetThumbElevationgetThumbElevation |
1dp |
| Halo color | app:haloColor |
setHaloTintListgetHaloTintList |
?attr/colorPrimary at 24% |
| Halo radius | app:haloRadius |
setHaloRadiusResourcesetHaloRadiusgetHaloRadius |
24dp |
| Attribute | Related method(s) | Default value | |
|---|---|---|---|
| Style | app:labelStyle |
N/A | @style/Widget.MaterialComponents.Tooltip |
| Formatter | N/A | setLabelFormatterhasLabelFormatter |
null |
| Behavior | app:labelBehavior |
setLabelBehaviorgetLabelBehavior |
floating |
Note: The value label is a Tooltip.
| Attribute | Related method(s) | Default value | |
|---|---|---|---|
| Color | app:tickColor |
setTickTintListgetTickTintList |
null |
| Color for track's active part | app:tickColorActive |
setTickActiveTintListgetTickActiveTintList |
?attr/colorOnPrimary at 54% |
| Color for track's inactive part | app:tickColorInactive |
setTickInactiveTintListgetTickInactiveTintList |
?attr/colorPrimary at 54% |
Note: app:tickColor takes precedence over app:tickColorActive and
app:tickColorInative. It's a shorthand for setting both values to the same
thing.
| Style | |
|---|---|
| Default style | Widget.MaterialComponents.Slider |
Default style theme attribute: ?attr/sliderStyle
See the full list of styles and attributes.
Sliders support Material Theming and can be customized in terms of color and typography.
API and source code:
SliderRangeSlider
The following example shows a range slider with Material Theming.
Using theme attributes and styles in res/values/styles.xml (themes all sliders
and affects other components):
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="colorOnSurface">@color/shrine_pink_100</item>
</style>or using a default style theme attribute, styles and a theme overlay (themes all sliders but does not affect other components):
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="sliderStyle">@style/Widget.App.Slider</item>
</style>
<style name="Widget.App.Slider" parent="Widget.MaterialComponents.Slider">
<item name="materialThemeOverlay">@style/ThemeOverlay.App.Slider</item>
<item name="labelStyle">@style/Widget.App.Tooltip</item>
</style>
<style name="ThemeOverlay.App.Slider" parent="">
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="colorOnSurface">@color/shrine_pink_100</item>
</style>
<style name="Widget.App.Tooltip" parent="Widget.MaterialComponents.Tooltip">
<item name="android:textAppearance">@style/TextAppearance.App.Tooltip</item>
<item name="backgroundTint">@color/shrine_pink_900</item>
</style>
<style name="TextAppearance.App.Tooltip" parent="TextAppearance.MaterialComponents.Tooltip">
<item name="android:textColor">@color/shrine_pink_100</item>
<item name="fontFamily">@font/rubik</item>
<item name="android:fontFamily">@font/rubik</item>
</style>or using the style in the layout (affects only this specific slider):
<com.google.android.material.slider.RangeSlider
...
style="@style/Widget.App.Slider" />









