I have a Jetpack Compose for Desktop UI application that shows a popup with a list of enums, each of which has a checkbox to toggle them:
Sorry for the long code, this is as small a MCVE as I could make of it.
enum class MyEnum {
A, B, C
}
data class MyFilter(val enums: Collection<MyEnum>)
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
App()
}
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun App() {
var filter by remember { mutableStateOf(MyFilter(emptyList())) }
MaterialTheme {
var show by remember { mutableStateOf(false) }
if (show) {
val selected = remember { filter.enums.toMutableStateList() }
AlertDialog({ show = false }, text = {
Column {
MyEnum.values().forEach { e ->
Row {
val isSelected by remember { derivedStateOf { e in selected } }
Checkbox(isSelected, { if (isSelected) selected.remove(e) else selected.add(e) })
Text(e.name)
}
}
}
}, buttons = {
Button({
filter = MyFilter(selected.toList())
show = false
}) { Text("OK") }
})
}
Button({ show = true }) { Text("Open") }
}
}
The problem here is, the very first time after opening the dialog, a click on a checkbox will properly update the underlying selected
list, but it won't update the UI. So the checkbox doesn't appear to change state. Every click after that will properly update the UI, including the changed state for the previous click.
This happens reliably, every single time the dialog is opened, but only on the first checkbox click.
Why does this happen, and how can I fix it?