In this post I will show you how to implement a custom DropDownMenu in Android Compose that tracks the current selection with a checkmark icon.
This is a fairly basic element but with a simple added feature to make it look better than out of the box. The checkmark will be added next to the currently selected DropDownMenuItem in the list each time the user accesses it.
Code
This is the entire Composable. The element is a DropDownMenu Composable with a static list. The DropDownMenuItems are created in a foreachIndexed function so the index could be used as part of the selection tracking.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
SampleDropDownMenuTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Box(modifier = Modifier.fillMaxSize().padding(innerPadding), contentAlignment = Alignment.TopCenter){
DropDownMenu()
}
}
}
}
}
}
@Composable
fun DropDownMenu() {
val categories: List<String> = listOf("Grocery", "Home", "Family", "Honey Do", "Work", "Bucket List", "Movies", "TV Shows", "Books", "Workout")
var selectedIndex by remember { mutableStateOf(0) }
var expanded by remember { mutableStateOf(false) }
Row(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
.clickable {
expanded = true
}, horizontalArrangement = Arrangement.SpaceBetween
){
OutlinedTextField(
modifier = Modifier
.fillMaxWidth(0.8f),
value = if(selectedIndex < categories.size) categories[selectedIndex] else categories[0],
enabled = false,
onValueChange = {
},
colors = TextFieldDefaults.colors(disabledTextColor = Color.Black),
textStyle = MaterialTheme.typography.bodyMedium,
trailingIcon = {
Icon(imageVector = Icons.Filled.ArrowDropDown, contentDescription = "Open Category Menu")
}
)
Box(modifier = Modifier.padding(5.dp),
contentAlignment = Alignment.BottomEnd) {
DropdownMenu(
modifier = Modifier.fillMaxWidth(0.85f).padding(5.dp),
expanded = expanded,
onDismissRequest = { expanded = false }
) {
categories.forEachIndexed { index, category ->
DropdownMenuItem(
onClick = {
selectedIndex = index
expanded = false
},
text = {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween){
Text(
text = category,
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(10.dp, bottom = 15.dp)
)
if(selectedIndex == index){
Icon(imageVector = Icons.Filled.Check, contentDescription = "Currently selected ${category}")
}
}
}
)
}
}
}
}
}
Hope this was useful.