items()
exist that holds 5 checkboxes, and the state of these can be controlled by a single parent variable as well as with a specific variable. The code is below: val areAllChecked = rememberSaveable {
mutableStateOf(false)
}
MyApplicationTheme {
LazyColumn(modifier = Modifier.fillMaxSize()) {
item {
IconButton(onClick = { areAllChecked.value = false }) {
Icon(imageVector = Icons.Default.Clear, contentDescription = null)
}
}
item {
Row(verticalAlignment = Alignment.CenterVertically){
Text(text = "Parent")
Checkbox(checked = areAllChecked.value, onCheckedChange = {
areAllChecked.value = it
})
}
}
items(5) {
val isChecked = rememberSaveable(areAllChecked.value) {
mutableStateOf(areAllChecked.value)
}
Row(verticalAlignment = Alignment.CenterVertically){
Text(text = it.toString())
Checkbox(checked = isChecked.value, onCheckedChange = {
isChecked.value = it
})
}
}
}
}
Here, areAllChecked
is a parent variable for controlling the state, and isChecked
is a local variable for checkboxes that changes when areAllChecked
gets changed as expected.
But when I press the icon button, all of the checkboxes' states will be false only if areAllChecked
is true. If it's not true, the local variable, which is isChecked
, remain unchanged when they should also be set to false, as the IconButton onClick triggers the areAllChecked
to false.
I've added the GIF here to show what I'm trying to solve.
How can i fix this?
Thank you.
You need to wrap your item into the Data
Class to manage the state of each item easily.
Here is the full example
Why use LaunchedEffect
because we don't want to load it every time. We want to change only when the CheckBox
of Parent changes.
Whenever changes are made in the single item we loop through and change its value and assign a new list to current.
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
data class CheckedItem(
val text: String, val isSelected: Boolean = false
)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Stack021(modifier: Modifier = Modifier) {
val list = listOf(
CheckedItem("A", false),
CheckedItem("B", false),
CheckedItem("C", false),
CheckedItem("D", false),
CheckedItem("E", false),
CheckedItem("F", false),
CheckedItem("G", false)
)
var useList by remember {
mutableStateOf(list)
}
val isAllAreCheck = rememberSaveable {
mutableStateOf(false)
}
LaunchedEffect(isAllAreCheck.value) {
useList = if (isAllAreCheck.value) {
useList.mapIndexed { j, item ->
item.copy(isSelected = true)
}
} else {
useList.mapIndexed { j, item ->
item.copy(isSelected = false)
}
}
}
Scaffold(topBar = {
TopAppBar(title = {
Text(text = "Multi Select Demo")
})
}) { padding ->
Column(
modifier = Modifier
.padding(padding)
.fillMaxSize()
) {
IconButton(onClick = {
println("All Are Unchecked")
useList = useList.mapIndexed { j, item ->
item.copy(isSelected = false)
}
}) {
Icon(imageVector = Icons.Default.Clear, contentDescription = null)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = "Parent")
Checkbox(
checked = isAllAreCheck.value,
onCheckedChange = {
isAllAreCheck.value = it
}
)
}
LazyColumn(
modifier = Modifier
.fillMaxSize()
.weight(1f)
) {
items(useList.size) { i ->
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = useList[i].text)
Checkbox(checked = useList[i].isSelected, onCheckedChange = {
useList = useList.mapIndexed { j, item ->
if (i == j) {
item.copy(isSelected = it)
} else item
}
})
}
}
}
}
}
}