The value of diabledValue is never updated. It always has value "A" How to properly chain mutableStates?
@Composable
fun DropDownDemo() {
var expanded by remember { mutableStateOf(false) }
val items = listOf("A", "B", "C", "d", "E", "F")
var selectedIndex by remember { mutableStateOf(0) }
var disabledValue by remember { mutableStateOf(items[selectedIndex]) }
Log.e("mcheck", "$selectedIndex $disabledValue")
Box(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.TopStart)
)
{
Text(
items[selectedIndex],
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = { expanded = true })
.background(Color.Gray)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.fillMaxWidth()
.background(Color.Red)
) {
items.forEachIndexed { index, s ->
DropdownMenuItem(onClick = {
selectedIndex = index
expanded = false
}) {
var disabledText = if (s == disabledValue) {
" Disabled"
} else {
""
}
Text(text = s + disabledText)
}
}
}
}
}
You actually don't need disabledValue to be State or remembered at all, so simply
val disabledValue = items[selectedIndex]
is the best thing you can do here. This is because getting item by index from array list is not expensive, and your composable has to recompose every time selectedIndex changes.
And to answer your question "How to properly chain mutableStates?" - if one of those wouldn't be the case, there is a derivedStateOf for such cases.
For example, if the calculation is somewhat expensive:
val list = ...
var selectedId by remember { mutableStateOf("...") }
val disabledValue by remember {
derivedStateOf {
list.find { it.id == selectedId }
}
}
Here, searching in a list is quite expensive calculation. With derivedStateOf, it will be done only when selectedId is changed. When your composable is recomposed because of some other change, derivedStateOf will use cached value and saves you that calculation.
And in this example:
val listState = rememberLazyListState()
val toolbarElevation by remember {
derivedStateOf {
if (listState.firstVisibleItemIndex == 0) 0.dp else 8.dp
}
}
TopAppBar(
elevation = toolbarElevation
)
listState.firstVisibleItemIndex is changing quite often when you scroll, but your composable have to recompose only when it changes from 0 to 1 and vice versa, and that's what derivedStateOf does for you.
derivedStateOf would also work for your case, but like I said, it's not necessary.
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