I have a LazyColumn with expandable items. And when i click on the item he expands or collapses, but i need that when i click on closed element it opens and others in the list close.(the one that open). So first i moved state of item from remember variable in the item's composable function to the list of dataClass elements. And when i click on item he execute callback that change value of it' selement in the list, but it doesn't recompose.
@Preview
@Composable
fun ExpandableCardList() {
val list = remember { mutableStateListOf(PointsCard(0),PointsCard(1),PointsCard(2),PointsCard(3),PointsCard(4),PointsCard(5))}
val state = rememberLazyListState()
Scaffold { paddingValues ->
LazyColumn(
state = state,
modifier = Modifier
.fillMaxWidth(),
contentPadding = paddingValues
) {
items(list, {it.key}) { item ->
ExpandableCard(
expanded = item.state,
state = {
bool -> item.state = bool
}
)
}
}
}
}
@Composable
fun ExpandableCard(expanded: Boolean, state: (bool:Boolean) -> Unit ){
Card(
Modifier
.fillMaxWidth()
.clickable { state(!expanded) }
.background(Color(Color.BLACK))
) {
Column(Modifier.background(Color(Color.BLACK)))
{
Box(
Modifier
.fillMaxWidth()
.height(54.dp)
.background(Color(Color.BLACK))
)
AnimatedVisibility(expanded) {
Box(
Modifier
.fillMaxWidth()
.padding(start = 10.dp)
.heightIn(56.dp, 300.dp)
.background(Color(Color.BLACK), shape = RoundedCornerShape(bottomStart = 8.dp)
)
)
}
}
}
}
data class PointsCard(
val key: Int = 0,
var state: Boolean = false
)
CodePudding user response:
If you want a single selection, you should probably consider hoisting your list in a class and perform all the structural changes via the list's iterator.
class CardListState {
val list = mutableStateListOf(PointsCard(0),PointsCard(1),PointsCard(2),PointsCard(3),PointsCard(4),PointsCard(5))
fun onSelected(isSelected: Boolean, item: PointsCard) {
val iterator = list.listIterator()
while (iterator.hasNext()) {
val obj = iterator.next()
if (obj.key != item.key) {
iterator.set(obj.copy(state = false))
} else {
iterator.set(obj.copy(state = isSelected))
}
}
}
}
@Composable
fun ExpandableCardList() {
val cardListState = remember { CardListState() }
val state = rememberLazyListState()
Scaffold { paddingValues ->
LazyColumn(
state = state,
modifier = Modifier
.fillMaxWidth(),
contentPadding = paddingValues
) {
items(cardListState.list, {it.key} ) { item ->
ExpandableCard(
expanded = item.state,
state = { bool ->
cardListState.onSelected(bool, item)
}
)
}
}
}
}
@Composable
fun ExpandableCard(
expanded: Boolean,
state: (bool:Boolean) -> Unit
) {
Card(
Modifier
.fillMaxWidth()
.clickable {
state(!expanded)
}
.background(Color.Black)
) {
Column(Modifier.background(Color.Black))
{
Box(
Modifier
.fillMaxWidth()
.height(54.dp)
.background(Color.Red)
)
AnimatedVisibility(expanded) {
Box(
Modifier
.fillMaxWidth()
.padding(start = 10.dp)
.heightIn(56.dp, 300.dp)
.background(Color.Green)
)
}
}
}
}