i have a Compose LazyColumnList which shows the content (from a List) in single cards. I want to highlight the selected card only. Now when i select another card, the first card stays highlighted. Here is the code:
...
LazyColumn(
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
) {
items(
items = sql_quran,
itemContent = { SurahListItem(quran_einzeln = it, navController)
})
}
@Composable
fun SurahListItem(
quran_einzeln: ItemData_quran,
navController: NavController,
) {
var selectedCard by remember { mutableStateOf(false) }
var cardColor = if (selectedCard) Blue else White;
// var cardColor= if (selectedCard) LightGray else White
Card(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 8.dp).fillMaxWidth().fillMaxSize(),
elevation = 2.dp,
shape = RoundedCornerShape(corner = CornerSize(16.dp)),
backgroundColor = cardColor,
onClick = {
selectedCard=!selectedCard
}
)
CodePudding user response:
All state changes are happening locally within your SurahListItem
and nothing tells your LazyColumn
to perform any updates to its item
children every time you click one of them.
I can't compile your entire code, so I just assumed some parts of it resulting to the codes below. I hoisted the "selection state" that you want one level above from your SurahListItem
and have the composable that contains the LazyColumn
do the updates.
You can copy-and-paste all of these in a single .kt
file and you'll be able to run it separately from some root composable screen/content.
data class ItemData_quran(val content: String)
@Composable
fun MyCards( sql_quran: List<ItemData_quran>) {
var selectedItem by remember {
mutableStateOf<ItemData_quran?>(null)
}
LazyColumn(
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
) {
items(
items = sql_quran,
itemContent = { surah ->
SurahListItem(
quran_einzeln = surah,
setSelected = selectedItem?.let {
surah.content == it.content
} ?: false
) {
selectedItem = it
}
}
)
}
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SurahListItem(
quran_einzeln: ItemData_quran,
setSelected: Boolean,
isSelected: (ItemData_quran?) -> Unit
) {
val cardColor = if (setSelected) Blue else White
Card(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 8.dp)
.wrapContentSize(),
elevation = 2.dp,
shape = RoundedCornerShape(corner = CornerSize(16.dp)),
backgroundColor = cardColor,
onClick = {
isSelected(if(!setSelected) quran_einzeln else null)
}
) {
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
Text(text = quran_einzeln.content)
}
}
}
Usage:
MyCards(
listOf(
ItemData_quran("Item 1"),
ItemData_quran("Item 2"),
ItemData_quran("Item 3"),
ItemData_quran("Item 4"),
ItemData_quran("Item 5"),
ItemData_quran("Item 6"),
ItemData_quran("Item 7"),
)
)