Reputation: 157
I'm wondering why my ExposedDropdownMenuBox
doesn't recomposed when the parent composable function parameters value changed.
@Composable
private fun Title(
isTitleEnabled: Boolean
) {
...
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if (isTitleEnabled){
expanded = !expanded
}
}
){...}
}
So why isTitleEnable value changed but ExposedDropdownMenuBox does not recomposed?
What I tried for now to solve the issue is to create a variable state then change it before passing it to the composable.
So my code after the changes looks something like this.
@Composable
private fun Title(
isTitleEnabled: Boolean
) {
...
var titleEnabled by remember { mutableStateOf(isTitleEnabled) }
titleEnabled = isTitleEnabled
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if (titleEnabled){
expanded = !expanded
}
}
){...}
}
After these changes my ExposedDropdownMenuBox recomposed, but I'm wondering why it doesn't before adding the state variable.
Upvotes: 1
Views: 837
Reputation: 106
It's understandable why the first case would skip ExposedDropdownMenuBox
in recompositions. That's simply because after the initial composition, it's not tied to isTitleEnabled
in the UI tree. You can think of it as taking an empty lambda for its onExpandedChange
which doesn't depend on any State
.
Another alternative to your workaround (which I think is fine) is to wrap ExposedDropdownMenuBox
with key(isTitleEnabled)
as such:
key(isTitleEnabled) {
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
if (isTitleEnabled) {
expanded = !expanded
}
}
) {...}
}
Upvotes: 2
Reputation: 554
In the second code piece you have published, you are trying to change the state while it is recomposing as the dropdown already consumes the expanded value, and on expanding change it also tries to consume the 'expanded change' inside again, which possibly cancels the recomposition because this creates a side effect.
What you can do is rather than having the if value inside your dropdown, use a launched effect that listens to the isTitleEnabled value such as:
LaunchedEffect(isTitleEnabled) {
if (isTitleEnabled) expanded = !expanded
}
I hope it helps as I can not understand how your expanded logic works as the codepieces you have published has no information about it. You can ask anything again on comments so I will edit my answer.
Upvotes: 2