I'm using the DropdownMenu
in Jetpack Compose, but I've got a problem that a lot of users doesn't understand that the menu contains more information so they can scroll the list. I get a lot of support that they're missing things from the list. Especially in some languages it nicely lines up the hight with an item, so you don't see that there are more items.
Is there a way to automatically set the height of the dropdown menu (no matter the language) so it displays half of an item at the bottom, so users understand that they can scroll the list?
I create the menu using these modifiers:
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.requiredSizeIn(maxHeight = 330.dp)
) {
items.forEachIndexed { index, item ->
DropdownMenuItem(onClick = {
onSelected(index, item.data)
selectedIndex = index
expanded = false
}) {
...
}
CodePudding user response:
I'm agree that this is a nice feature to have, I suggest you create a feature request on the Compose issue tracker.
Here's a workaround for now, you can get your item heights using Modifier.onSizeChanged
and update your maxHeight
constraint like this:
@Composable
fun TestScreen(
) {
var expanded by remember { mutableStateOf(true) }
val items = List(10) { it.toString() }
val itemHeights = remember { mutableStateMapOf<Int, Int>() }
val baseHeight = 330.dp
val density = LocalDensity.current
val maxHeight = remember(itemHeights.toMap()) {
if (itemHeights.keys.toSet() != items.indices.toSet()) {
// if we don't have all heights calculated yet, return default value
return@remember baseHeight
}
val baseHeightInt = with(density) { baseHeight.toPx().toInt() }
// top bottom system padding
var sum = with(density) { DropdownMenuVerticalPadding.toPx().toInt() } * 2
for ((i, itemSize) in itemHeights.toSortedMap()) {
sum = itemSize
if (sum >= baseHeightInt) {
return@remember with(density) { (sum - itemSize / 2).toDp() }
}
}
// all items fit into base height
baseHeight
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.requiredSizeIn(maxHeight = maxHeight)
) {
items.forEachIndexed { index, item ->
DropdownMenuItem(
onClick = {
onSelected(index, item.data)
selectedIndex = index
expanded = false
},
modifier = Modifier.onSizeChanged {
itemHeights[index] = it.height
}
) {
Text("Hello $index", modifier = Modifier.padding(30.dp))
}
}
}
}
private val DropdownMenuVerticalPadding = 8.dp
p.s. DropdownMenuVerticalPadding
is a Material constant taken from the source code.