Выделите только одну карту в Compose путем выбора

у меня есть Compose LazyColumnList, который показывает содержимое (из списка) в отдельных карточках. Я хочу выделить только выбранную карту. Теперь, когда я выбираю другую карту, первая карта остается выделенной. Вот код:

...
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
    }

)
3
0
176
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Все изменения состояния происходят локально в вашем SurahListItem, и ничто не говорит вашему LazyColumn выполнять какие-либо обновления для своих item дочерних элементов каждый раз, когда вы нажимаете на один из них.

Я не могу скомпилировать весь ваш код, поэтому я просто предположил, что некоторые его части приводят к приведенным ниже кодам. Я поднял «состояние выбора», которое вы хотите на один уровень выше вашего SurahListItem, и компонуемый объект, содержащий LazyColumn, выполняет обновления.

Вы можете скопировать и вставить все это в один файл .kt, и вы сможете запускать его отдельно от какого-либо корневого составного экрана/контента.

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)
        }
    }
}

Применение:

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

Другие вопросы по теме