Home > OS >  Highlight only one Card in Compose through selection
Highlight only one Card in Compose through selection

Time:11-07

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"),
          )
)

enter image description here

  • Related