
Modular, customizable wheel-style picker: supply custom item and window components, style items by position, adjust buffer, animation and scroll friction, plus animated programmatic scrolling.
KMP Wheel Picker provides a modular wheel picker for Compose Multiplatform.
KMP Wheel Picker is on Maven Central. It supports Android, iOS, desktop, and web (via Kotlin/Wasm).
[versions]
kmpWheelPicker = "0.3.0"
[libraries]
swmansion-kmpWheelPicker = { module = "com.swmansion.kmpwheelpicker:kmp-wheel-picker", version.ref = "kmpWheelPicker" }dependencies { implementation(libs.swmansion.kmpWheelPicker) }Create a
WheelPickerState
instance using
rememberWheelPickerState.
Define the item count and, optionally, the index of the initially selected item.
val state = rememberWheelPickerState(itemCount = 15, initialIndex = 7)Use
WheelPicker
to display a wheel picker. Pass in the
WheelPickerState
instance, and define an item-drawing lambda:
WheelPicker(state) { Text("Item $it", Modifier.padding(16.dp, 8.dp)) }Add a window:
WheelPicker(
state = state,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { index ->
Text("Item ${index + 1}", Modifier.padding(16.dp, 8.dp))
}bufferSize defines the number of items shown above and below the window:
WheelPicker(
state = state,
bufferSize = 3,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { index ->
Text("Item ${index + 1}", Modifier.padding(16.dp, 8.dp))
}Style items based on position by comparing their indexes to
WheelPickerState.value.
Here, we make the selected item use
MaterialTheme.colorScheme.primary,
and add fade-out at the top and bottom:
private const val BUFFER_SIZE = 3WheelPicker(
state = state,
bufferSize = BUFFER_SIZE,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { index ->
Text(
text = "Item ${index + 1}",
modifier =
Modifier.padding(16.dp, 8.dp).graphicsLayer {
alpha = (BUFFER_SIZE - abs(state.value - index)).coerceIn(0f, 1f)
},
color =
lerp(
MaterialTheme.colorScheme.primary,
MaterialTheme.colorScheme.onSurfaceVariant,
abs(state.value - index).coerceIn(0f, 1f),
),
)
}Additionally, use modifier to add modifiers; animationSpec to customize animated scroll and
snapping; and friction to adjust the scroll friction, used for snapping:
WheelPicker(
state = state,
modifier = Modifier.align(Alignment.Center),
bufferSize = 3,
animationSpec = spring(Spring.DampingRatioLowBouncy, Spring.StiffnessMediumLow),
friction = 8f,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { /* ... */ }WheelPickerState.index
stores the index of the currently selected item:
LaunchedEffect(state.index) { println("Item ${state.index + 1} selected.") }Through
WheelPickerState,
you can also access the wheel picker’s
InteractionSource
instance and slot height, as well as scroll programmatically, with or without an animation.
Founded in 2012, Software Mansion is a software agency with experience in building web and mobile apps. We are core React Native contributors and experts in dealing with all kinds of React Native issues. We can help you build your next dream product—hire us.
Patryk Goworowski is a senior Android developer at Wakacje.pl and coauthor of Vico.
KMP Wheel Picker provides a modular wheel picker for Compose Multiplatform.
KMP Wheel Picker is on Maven Central. It supports Android, iOS, desktop, and web (via Kotlin/Wasm).
[versions]
kmpWheelPicker = "0.3.0"
[libraries]
swmansion-kmpWheelPicker = { module = "com.swmansion.kmpwheelpicker:kmp-wheel-picker", version.ref = "kmpWheelPicker" }dependencies { implementation(libs.swmansion.kmpWheelPicker) }Create a
WheelPickerState
instance using
rememberWheelPickerState.
Define the item count and, optionally, the index of the initially selected item.
val state = rememberWheelPickerState(itemCount = 15, initialIndex = 7)Use
WheelPicker
to display a wheel picker. Pass in the
WheelPickerState
instance, and define an item-drawing lambda:
WheelPicker(state) { Text("Item $it", Modifier.padding(16.dp, 8.dp)) }Add a window:
WheelPicker(
state = state,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { index ->
Text("Item ${index + 1}", Modifier.padding(16.dp, 8.dp))
}bufferSize defines the number of items shown above and below the window:
WheelPicker(
state = state,
bufferSize = 3,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { index ->
Text("Item ${index + 1}", Modifier.padding(16.dp, 8.dp))
}Style items based on position by comparing their indexes to
WheelPickerState.value.
Here, we make the selected item use
MaterialTheme.colorScheme.primary,
and add fade-out at the top and bottom:
private const val BUFFER_SIZE = 3WheelPicker(
state = state,
bufferSize = BUFFER_SIZE,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { index ->
Text(
text = "Item ${index + 1}",
modifier =
Modifier.padding(16.dp, 8.dp).graphicsLayer {
alpha = (BUFFER_SIZE - abs(state.value - index)).coerceIn(0f, 1f)
},
color =
lerp(
MaterialTheme.colorScheme.primary,
MaterialTheme.colorScheme.onSurfaceVariant,
abs(state.value - index).coerceIn(0f, 1f),
),
)
}Additionally, use modifier to add modifiers; animationSpec to customize animated scroll and
snapping; and friction to adjust the scroll friction, used for snapping:
WheelPicker(
state = state,
modifier = Modifier.align(Alignment.Center),
bufferSize = 3,
animationSpec = spring(Spring.DampingRatioLowBouncy, Spring.StiffnessMediumLow),
friction = 8f,
window = {
Box(
Modifier.background(
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f),
MaterialTheme.shapes.small,
)
)
},
) { /* ... */ }WheelPickerState.index
stores the index of the currently selected item:
LaunchedEffect(state.index) { println("Item ${state.index + 1} selected.") }Through
WheelPickerState,
you can also access the wheel picker’s
InteractionSource
instance and slot height, as well as scroll programmatically, with or without an animation.
Founded in 2012, Software Mansion is a software agency with experience in building web and mobile apps. We are core React Native contributors and experts in dealing with all kinds of React Native issues. We can help you build your next dream product—hire us.
Patryk Goworowski is a senior Android developer at Wakacje.pl and coauthor of Vico.