Cannot make ExposedDropdownMenu same width as OutlinedTextField
I faced the following problem - items of the dropdown are not the same width as OutlinedTextField
Looked for the solution - found the following:
-
Add the variable to keep
textField
width:var textFieldSize by remember { mutableStateOf(Size.Zero) }
-
Set the value in the
onGloballyPositioned
ofTextField
onGloballyPositioned { coordinates -> textFieldSize = coordinates.size.toSize() }
-
Read the value in
ExposedDropdownMenu
ExposedDropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, modifier = Modifier .background(Color.White) .width(with(LocalDensity.current) { textFieldSize.width.toDp() }) )
The problem is that it works fine with DropdownMenu
, but doesn't work with ExposedDropdownMenu
. What's the problem?
Here's the full code:
var expanded by remember { mutableStateOf(false) }
val sexList by remember { mutableStateOf(listOf("Male", "Female")) }
var textFieldSize by remember { mutableStateOf(Size.Zero) }
val icon = if (expanded)
Icons.Filled.ArrowDropUp
else
Icons.Filled.ArrowDropDown
ExposedDropdownMenuBox(
modifier = modifier
.clickable(onClick = { expanded = true }),
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
OutlinedTextField(
value = "",
onValueChange = {},
modifier = Modifier
.fillMaxWidth()
.onGloballyPositioned { coordinates ->
textFieldSize = coordinates.size.toSize()
},
colors = TextFieldDefaults.textFieldColors(
backgroundColor = BorderColor,
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = BrandColor,
focusedLabelColor = BrandColor,
),
leadingIcon = {
Image(
painter = painterResource(id = R.drawable.ic_complete_registration_sex),
contentDescription = null
)
},
trailingIcon = { Icon(icon, null) },
shape = RoundedCornerShape(Dimen.Dimen14),
label = {
Text(
"Choose Gender",
style = PoppinsNormalStyle14
)
},
readOnly = true
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.background(Color.White)
.width(with(LocalDensity.current) { textFieldSize.width.toDp() })
) {
sexList.forEach {
DropdownMenuItem(
onClick = { expanded = false },
) {
Text(it, style = PoppinsNormalStyle12Gray2)
}
}
}
}
ExposedDropdownMenuBox
is built to calculate width for you so you don't have to use all this onGloballyPositioned
related logic.
The fact that it doesn't work is a known issue.
Until it's fixed it's recommended to use DropdownMenu
with Modifier.exposedDropdownSize()
(this modifier will apply the width calculated by ExposedDropdownMenuBox
) instead of ExposedDropdownMenu
:
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.background(Color.White)
.exposedDropdownSize()
) {
sexList.forEach {
DropdownMenuItem(
onClick = { expanded = false },
) {
Text(it, style = PoppinsNormalStyle12Gray2)
}
}
}