# Slider
[Sliders](https://m3.material.io/components/sliders/) let users make selections
from a range of values. There are three variants of sliders.

1. Standard
2. Centered
3. Range
**Note:** Images use various dynamic color schemes.
## Design & API documentation
* [Material 3 (M3) spec](https://m3.material.io/components/sliders/overview/)
* [API reference](https://developer.android.com/reference/com/google/android/material/slider/package-summary)
## Anatomy

1. Value indicator (optional)
2. Stop indicators (optional)
3. Active track
4. Handle
5. Inactive track
6. Inset icon (optional)
More details on anatomy items in the
[component guidelines](https://m3.material.io/components/sliders/guidelines#b3701f5e-128a-4807-bca7-033402b4266a).
## M3 Expressive
### M3 Expressive update
Before you can use `Material3Expressive` component styles, follow the
[`Material3Expressive themes` setup instructions](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md#material3expressive-themes).
The slider includes expressive configurations for orientation, shape sizes, and
an inset icon.
[More on M3 Expressive](https://m3.material.io/blog/building-with-m3-expressive)
**Types and naming:**
* Changed **continuous** slider to **standard** slider
* The **discrete** slider is now the **stops** configuration
**New configurations:**
* Orientation: Horizontal, vertical
* Optional inset icon (standard slider only)
* Sizes: XS (existing default), S, M, L, XL
### M3 Expressive styles
The expressive slider comes with 5 pre-defined styles varying in track thickness
and corner size:
- `Widget.Material3Expressive.Slider.Xsmall` (default)
- `Widget.Material3Expressive.Slider.Small`
- `Widget.Material3Expressive.Slider.Medium`
- `Widget.Material3Expressive.Slider.Large`
- `Widget.Material3Expressive.Slider.Xlarge`
## Key properties
### Track attributes
Element | Attribute | Related method(s) | Default value
------------------------------------------ | ----------------------------- | ------------------------------------------------------------- | -------------
**Orientation** | `android:orientation` | `setOrientation`
`isVertical` | `horizontal`
**Min value** | `android:valueFrom` | `setValueFrom`
`getValueFrom` | N/A
**Max value** | `android:valueTo` | `setValueTo`
`getValueTo` | N/A
**Step size (discrete)** | `android:stepSize` | `setStepSize`
`getStepSize` | N/A
**Initial selected value (Slider)** | `android:value` | `setValue`
`getValue` | N/A
**Initial selected values (RangeSlider)** | `app:values` | `setValues`
`getValues` | N/A
**Centered** | `app:centered` | `setCentered`
`isCentered` | `false`
**Continuous mode tick count** | `app:continuousModeTickCount` | `setContinuousModeTickCount`
`getContinuousModeTickCount` | 0
**Height** | `app:trackHeight` | `setTrackHeight`
`getTrackHeight` | `16dp`
**Color** | `app:trackColor` | `setTrackTintList`
`getTrackTintList` | `null`
**Color for track's active part** | `app:trackColorActive` | `setTrackActiveTintList`
`getTrackActiveTintList` | `?attr/colorPrimary`
**Color for track's inactive part** | `app:trackColorInactive` | `setTrackInactiveTintList`
`getTrackInactiveTintList` | `?attr/colorSurfaceContainerHighest`
**Corner size** | `app:trackCornerSize` | `setTrackCornerSize`
`getTrackCornerSize` | `trackHeight / 2`
**Inside corner size** | `app:trackInsideCornerSize` | `setTrackInsideCornerSize`
`getTrackInsideCornerSize` | `2dp`
**Stop indicator size** | `app:trackStopIndicatorSize` | `setTrackStopIndicatorSize`
`getTrackStopIndicatorSize` | `4dp`
**Minimum separation for adjacent thumbs** | `app:minSeparation` | `setMinSeparation`
`getMinSeparation` | `0dp`
**Active start icon** | `app:trackIconActiveStart` | `setTrackIconActiveStart`
`getTrackIconActiveStart` | `null`
**Active end icon** | `app:trackIconActiveEnd` | `setTrackIconActiveEnd`
`getTrackIconActiveEnd` | `null`
**Active icon color** | `app:trackIconActiveColor` | `setTrackIconActiveColor`
`getTrackIconActiveColor` | N/A
**Inactive start icon** | `app:trackIconInactiveStart` | `setTrackIconInactiveStart`
`getTrackIconInactiveStart` | `null`
**Inactive end icon** | `app:trackIconInactiveEnd` | `setTrackIconInactiveEnd`
`getTrackIconInactiveEnd` | `null`
**Inactive icon color** | `app:trackIconInactiveColor` | `setTrackIconInactiveColor`
`getTrackIconInactiveColor` | N/A
**Icon size** | `app:trackIconSize` | `setTrackIconSize`
`getTrackIconSize` | N/A
**Note:** `app:trackColor` takes precedence over `app:trackColorActive` and
`app:trackColorInative`. It's a shorthand for setting both values to the same
thing.
**Note:** `app:trackStopIndicatorSize` takes precedence over
`app:tickRadiusActive` and `app:tickRadiusInactive`.
**Note:** `vertical` orientation still uses `height` in the same way as for
`horizontal` orientation. In this context, `height` can be seen as track
thickness.
### Thumb attributes
Element | Attribute | Related method(s) | Default value
---------------- | ----------------------- | --------------------------------------------------------------------------------- | -------------
**Color** | `app:thumbColor` | `setThumbTintList`
`getThumbTintList` | `?attr/colorPrimary`
**Width** | `app:thumbWidth` | `setThumbWidth`
`setThumbWidthResource`
`getThumbWidth` | `4dp`
**Height** | `app:thumbHeight` | `setThumbHeight`
`setThumbHeightResource`
`getThumbHeight` | `44dp`
**Radius** | `app:thumbRadius` | `setThumbRadiusResource`
`setThumbRadius`
`getThumbRadius` | N/A
**Elevation** | `app:thumbElevation` | `setThumbElevationResource`
`setThumbElevation`
`getThumbElevation` | `2dp`
**Halo color** | `app:haloColor` | `setHaloTintList`
`getHaloTintList` | `@android:color/transparent`
**Halo radius** | `app:haloRadius` | `setHaloRadiusResource`
`setHaloRadius`
`getHaloRadius` | N/A
**Stroke color** | `app:thumbStrokeColor` | `setThumbStrokeColor`
`setThumbStrokeColorResource`
`getThumbStrokeColor` | `null`
**Stroke width** | `app:thumbStrokeWidth` | `setThumbStrokeWidth`
`setThumbStrokeWidthResource`
`getThumbStrokeWidth` | `0dp`
**Gap size** | `app:thumbTrackGapSize` | `setThumbTrackGapSize`
`getThumbTrackGapSize` | `6dp`
**Note:** `app:thumbWidth` and `app:thumbHeight` take precedence over
`app:thumbRadius`.
### Value label attributes
Element | Attribute | Related method(s) | Default value
------------- | ------------------- | ------------------------------------------- | -------------
**Style** | `app:labelStyle` | N/A | `@style/Widget.Material3.Tooltip`
**Formatter** | N/A | `setLabelFormatter`
`hasLabelFormatter` | `null`
**Behavior** | `app:labelBehavior` | `setLabelBehavior`
`getLabelBehavior` | `floating`
**Note:** The value label is a
[Tooltip](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tooltip/TooltipDrawable.java).
### Tick mark attributes
Element | Attribute | Related method(s) | Default value
----------------------------------- | ------------------------ | ------------------------------------------------------- | -------------
**Color** | `app:tickColor` | `setTickTintList`
`getTickTintList` | `null`
**Color for tick's active part** | `app:tickColorActive` | `setTickActiveTintList`
`getTickActiveTintList` | `?attr/colorSurfaceContainerHighest`
**Color for tick's inactive part** | `app:tickColorInactive` | `setTickInactiveTintList`
`getTickInactiveTintList` | `?attr/colorPrimary`
**Radius for tick's active part** | `app:tickRadiusActive` | `setTickActiveRadius`
`getTickActiveRadius` | `null` (1/2 trackStopIndicatorSize)
**Radius for tick's inactive part** | `app:tickRadiusInactive` | `setTickInactiveRadius`
`getTickInactiveRadius` | `null` (1/2 trackStopIndicatorSize)
**Tick visible** (deprecated) | `app:tickVisible` | `setTickVisible`
`isTickVisible()` | `true`
**Tick visibility mode** | `app:tickVisibilityMode` | `setTickVisibilityMode`
`getTickVisibilityMode()` | `autoLimit`
**Note:** `app:tickColor` takes precedence over `app:tickColorActive` and
`app:tickColorInactive`. It's a shorthand for setting both values to the same
thing.
**Note:** `app:tickVisible` is deprecated in favor of `app:tickVisibilityMode`.
### Styles
Element | Style | Theme attribute
----------------- | ------------------------- | -------------------
**Default style** | `Widget.Material3.Slider` | `?attr/sliderStyle`
For the full list, see
[styles](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/slider/res/values/styles.xml)
and
[attributes](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/slider/res/values/attrs.xml).
### Non-text contrast update
In order to comply with the latest accessibility requirements, the `Slider` has
been updated with additional attributes:
- `app:thumbTrackGapSize`: size of the gap between the thumb and the track,
6dp by default.
- `app:trackInsideCornerSize`: size of the corners towards the thumb when a
gap is present, 2dp by default.
- `app:trackStopIndicatorSize`: size of the stop at the start/end of the
track, 4dp by default.
`*.Legacy` styles have been added to revert to the previous behavior (**not
recommended**):
- `Widget.Material3.Slider.Legacy`
## Variants of sliders
### Standard slider
Standard sliders select one value from a range of values. Use this when the
slider should start from zero or the beginning of a sequence.
API and source code:
* `Slider`
* [Class definition](https://developer.android.com/reference/com/google/android/material/slider/Slider)
* [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/slider/Slider.java)
**Add a `Standard slider` to a layout:**
```xml
```
**Add a `standard slider with stop indicator` to a layout:**
Stop indicators show which predetermined values can be chosen on the slider. The
slider handle snaps to the closest stop.
```xml
```
**Observe changes to a slider:**
```kt
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
}
```
### Centered slider
Centered sliders select a value from a positive and negative value range. Use
this when zero, or the default value, is in the middle of the range.
**Add a `centered slider` to a layout:**
```xml
```
### Range slider
A slider with two thumbs is called a range slider. Range sliders select two
values on one slider to create a range. Use this when defining a minimum and
maximum value.
* `RangeSlider`
* [Class definition](https://developer.android.com/reference/com/google/android/material/slider/RangeSlider)
* [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/slider/RangeSlider.java)
**Add a `range slider` to a layout:**
```xml
```
**Add a `range slider with stop indicator` to a layout:**
Stop indicators show which predetermined values can be chosen on the slider. The
slider handle snaps to the closest stop.
```xml
```
And in `values/arrays.xml`:
```xml
- 20.0
- 70.0
```
**Observe changes to a range slider:**
```kt
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
}
```
## Code implementation
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](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md)
page.
### Making sliders accessible
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:
```kt
slider.contentDescription = contentDescription
```
If using a `TextView` to display the value of the slider, you should set
`android:labelFor` so that screen readers announce that `TextView` refers to the
slider.
The minimum touch target size of the thumb is 48dp by default. If a different
size is needed, please set `minTouchTargetSize` in the style or the layout.
### Setting a `LabelFormatter`
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 price range in USD currency.
In code:
```kt
rangeSlider.setLabelFormatter { value: Float ->
val format = NumberFormat.getCurrencyInstance()
format.maximumFractionDigits = 0
format.currency = Currency.getInstance("USD")
format.format(value.toDouble())
}
```
## Customizing sliders
### Theming sliders
Sliders support
[Material Theming](https://material.io/components/sliders#theming) which can
customize color and typography.
#### Slider theming example
API and source code:
* `Slider`
* [Class definition](https://developer.android.com/reference/com/google/android/material/slider/Slider)
* [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/slider/Slider.java)
The following example shows a range slider with Material theming.

##### Implementing slider theming
Use theme attributes and styles in `res/values/styles.xml` which applies to all
sliders and affects other components:
```xml
```
Use a default style theme attribute, styles and a theme overlay which applies to
all sliders but does not affect other components:
```xml
```
Use the style in the layout, which affects only this specific slider:
```xml
```