Compose Android Dropdown Menu
In this article, we are going to integrate dropdown menu in mobile application using jetpack compose android. You can also check out jetpack compose related articles.
menuItems parameter is used to display items in list in dropdown menu. selectedIndex is used to get position of current selected item in dropdown menu. menuExpandedState is used to detect whether dropdown menu is expanded or not.
updateMenuExpandStatus is used to change state to display dropdown menu via recomposition. onMenuItemClick is used to detect click of item in dropdown menu. onDismissMenuView is used to detect when menu is dismissed.
Add required dependency in app level build.gradle file
Jetpack Compose Dropdown Menu
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun MyDropdownMenu(){
val listFootballPlayers = listOf(“Cristiano Ronaldo”, “Paul Pogba”, “Jadon Sancho”, “Raphael Varane”, “David de Gea”)
var dropdownMenuExpanded by remember { mutableStateOf(false) }
var selectedIndex by remember { mutableStateOf(0) }
Box(
modifier = Modifier
.fillMaxSize()
.padding(20.dp),
contentAlignment = Alignment.Center
) {
MyDropdownMenuLayout(
selectedIndex = selectedIndex,
menuExpandedState = dropdownMenuExpanded,
menuItems = listFootballPlayers,
onDismissMenuView = {
dropdownMenuExpanded = false
},
updateMenuExpandStatus = {
dropdownMenuExpanded = true
},
onMenuItemclick = { index->
selectedIndex = index
dropdownMenuExpanded = false
}
)
}
}
Compose Android Dropdown Menu Layout
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
@Composable
fun MyDropdownMenuLayout(
menuItems: List<String>,
menuExpandedState: Boolean,
selectedIndex : Int,
updateMenuExpandStatus : () -> Unit,
onDismissMenuView : () -> Unit,
onMenuItemclick : (Int) -> Unit,
) {
Box(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.TopStart)
.border(0.5.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.5f))
.clickable(
onClick = {
updateMenuExpandStatus()
},
),
) {
ConstraintLayout(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
val (label, iconView) = createRefs()
Text(
text = menuItems[selectedIndex],
modifier = Modifier
.fillMaxWidth()
.constrainAs(label) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(iconView.start)
width = Dimension.fillToConstraints
}
)
val displayIcon: Painter = painterResource(
id = android.R.drawable.arrow_down_float
)
Icon(
modifier = Modifier
.size(18.dp, 18.dp)
.constrainAs(iconView) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
end.linkTo(parent.end)
},
tint = MaterialTheme.colors.onSurface,
painter = displayIcon,
contentDescription = null,
)
DropdownMenu(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.surface),
expanded = menuExpandedState,
onDismissRequest = { onDismissMenuView() },
) {
menuItems.forEachIndexed { index, title ->
DropdownMenuItem(
onClick = {
if (index != 0) {
onMenuItemclick(index)
}
}) {
Text(text = title)
}
}
}
}
}
}

