Below is a simple composable function, when I log the pd object it prints the current value of the retained(boolean) field. But after initializing the isChecked variable the value is always !pd.retained. Therefore, the state of my switch is always incorrect.
@Composable
fun DocumentModalSheet( pd: PrintDocument,
onSwitchSelected: (id: Long, status: Boolean) -> Unit,
) {
Log.i("DocumentModalSheet", "DocumentModalSheet: ${pd.retained}")
// This prints the correct value of pd.retained
var isChecked by remember {
mutableStateOf(pd.retained)
}
Log.i("DocumentModalSheet", "DocumentModalSheet: $isChecked")
// This prints the incorrect value of pd.retained
Column(
modifier = Modifier.fillMaxWidth()
) {
Switch(checked = isChecked, onCheckedChange = {
isChecked = it,
onSwitchSelected(pd.id, it)
} )
}}
This is how I am calling the above function from PrintDocumentScreen composable.
When the lambda of DocumentCard is called, I am updating the clickedPD variable and showing the modal sheet.
@Composable
fun PrintDocumentScreen(viewModel: PrintDocumentViewModel) {
val pdListFlow = viewModel.pdListFlow.collectAsState()
var clickedPD by remember { mutableStateOf(PrintDocument()) }
val modalSheetState = rememberModalBottomSheetState(..)
ModalBottomSheetLayout(
sheetContent = {
DocumentModalSheet(clickedPD){
viewModel.doSomething(id, status)
}
},
content = {
Scaffold(modifier = Modifier.fillMaxSize()) { paddingValues ->
Column(modifier = Modifier.fillMaxSize().padding(paddingValues)
) {
pdListFlow.value?.let { it ->
when (it) {
is Resource.Success -> {
if (it.data.printDocuments.isNotEmpty()) {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(it.data.printDocuments.size) { index ->
DocumentCard(it.data.printDocuments[index]) {
clickedPD = it
coroutineScope.launch {
modalSheetState.show()
}
}
}
}
} else {
NoDocumentPresent()
}
}
}
}
}}})}
What I have tried so far…
I tried hoisting the isChecked initialization part to the PrintDocumentScreen but it didn’t help.
I also used derivedStateOf() to intitialize the isChecked variable in the PrintDocumentScreen
var clickedPD by remember { mutableStateOf(PrintDocument()) }
val isChecked by remember {
derivedStateOf { clickedPD.retained }
}
I have noticed that the state of switch is shared by all the DocumentCard(s), because when I check a switch, hide the modal sheet, tap on another card, the switch is already selected.
>Solution :
Yes, you’ve told Compose to remember the value, so that’s what it does.
If you want a new value when pd changes, you have to tell it do do that:
var isChecked by remember(pd) {
mutableStateOf(pd.retained)
}
