I found that when there is a lot of data, ExposedDropdownMenuBox will have performance problems.
So I did some searching and found this issue, it says that LazyColumn
can be used to improve performance.
But I am getting the following error:
java.lang.IllegalStateException: Asking for intrinsic measurements of SubcomposeLayout layouts is not supported. This includes components that are built on top of SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate this:
if intrinsic measurements are used to achieve 'match parent' sizing,, consider replacing the parent of the component with a custom layout which controls the order in which children are measured, making intrinsic measurement not needed adding a size modifier to the component, in order to fast return the queried intrinsic measurement.
Here is the complete code:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SageExposedDropdownMenuBox(options: List<DropDownMenuOption>) {
var expanded by remember { mutableStateOf(false) }
var selected by remember { mutableStateOf<DropDownMenuOption?>(null) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
TextField(
value = selected?.label ?: "",
onValueChange = {
},
readOnly = true,
modifier = Modifier.menuAnchor()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
LazyColumn {
items(options) { option ->
DropdownMenuItem(
text = { Text(text = option.label) },
onClick = {
selected = option
expanded = false
}
)
}
}
}
}
}
I just started to learn jetpack compose, I don't know what intrinsic measurements
and ExposedDropdownMenuBox
internal structure.
please tell me how to fix this error.
Until this is properly supported, consider the following workaround: Hard code the lazy column's height based on the single item's height and the maximum height that popup can take. Similarly, adjust the width according to your use case.
val sizeOfOneItem by remember {
mutableStateOf(50.dp) //assuming height of one menu item 50dp
}
val configuration = LocalConfiguration.current
val screenHeight50 by remember {
val screenHeight = configuration.screenHeightDp.dp
mutableStateOf(screenHeight / 2) //assuming the drop down menu anchor is in middle of the screen. This is the maximum height that popup menu can take.
}
val height by remember(options.size) {
val itemsSize = sizeOfOneItem * options.size
mutableStateOf(minOf(itemsSize, screenHeight50))
}
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
LazyColumn(
modifier = Modifier
.width(500.dp)
.height(height)
) {
items(options) { option ->
DropdownMenuItem(
onClick = {},
text = {
Text(text = option.label)
}
)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With