In Jetpack Compose, there’s no direct equivalent to the traditional Spinner
widget from the View-based UI system. However, you can implement a dropdown menu using DropdownMenu
or ExposedDropdownMenuBox
, which serve a similar purpose.
Example of Dropdown Using DropdownMenu
This example demonstrates creating a dropdown menu where users can select an item.
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun SimpleSpinner() {
var expanded by remember { mutableStateOf(false) }
val items = listOf("Option 1", "Option 2", "Option 3")
var selectedItem by remember { mutableStateOf(items[0]) }
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = selectedItem,
modifier = Modifier
.fillMaxWidth()
.clickable { expanded = true }
.padding(16.dp),
style = MaterialTheme.typography.bodyLarge
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.fillMaxWidth()
) {
items.forEach { label ->
DropdownMenuItem(
text = { Text(label) },
onClick = {
selectedItem = label
expanded = false
}
)
}
}
}
}
Example of ExposedDropdownMenuBox
ExposedDropdownMenuBox
provides a more modern and Material 3-compliant dropdown.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExposedDropdownMenuExample() {
val items = listOf("Option 1", "Option 2", "Option 3")
var expanded by remember { mutableStateOf(false) }
var selectedItem by remember { mutableStateOf(items[0]) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
TextField(
value = selectedItem,
onValueChange = {},
readOnly = true,
label = { Text("Select an option") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
},
modifier = Modifier.menuAnchor()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
items.forEach { selectionOption ->
DropdownMenuItem(
text = { Text(selectionOption) },
onClick = {
selectedItem = selectionOption
expanded = false
}
)
}
}
}
}
Key Features
- DropdownMenu:
- Flexible and customizable.
- Can be used in various scenarios, not limited to “selectable” menus.
- ExposedDropdownMenuBox:
- Specifically designed for dropdown menus.
- Automatically aligns menus with TextFields and provides Material styling.
- State Management:
- Manage expanded state using
remember
. - Track selected items dynamically.
When to Use
- Use
DropdownMenu
for highly custom scenarios. - Use
ExposedDropdownMenuBox
for standard dropdowns, ensuring consistency with Material Design principles.
These composables allow you to build dropdowns in Jetpack Compose with the flexibility to style them however you need.