Составьте LazyColumn выберите один элемент

Я хочу выбрать один элемент своего LazyColumn и изменить цвет текста. Как можно определить, какой элемент выбран?

Код:

      val items = listOf(Pair("A", 1), Pair("AA", 144), Pair("BA", 99))
var selectedItem by mutableStateOf(items[0])
LazyColumn {
    this.items(items = items) {
        Row(modifier = Modifier.clickable(onClick = {selectedItem = it}) {
            if (selectedItem == it) {
                Text(it.first, color = Color.Red)
            } else {
                Text(it.first)
            }
        }
    }
}

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

3 ответа

Решение

Вы можете использовать <strong> <tcode id="51066827"></tcode></strong> модификатор вместо .clickable

Что-то вроде:

      data class Message(val id: Int,
                   val message : String)
val messages : List<Message> = listOf(...))

val listState = rememberLazyListState()
var selectedIndex by remember{mutableStateOf(-1)}
 
LazyColumn(state = listState) {
        items(items = messages) { message ->

            Text(
                text = message.message,
                modifier = Modifier
                    .fillMaxWidth()
                    .background(
                        if (message.id == selectedIndex)
                            Color.Red else Color.Yellow
                    )
                    .selectable(
                        selected = message.id == selectedIndex,
                        onClick = { if (selectedIndex != message.id)
                             selectedIndex = message.id else selectedIndex = -1})
            )
        }
 }

В вашем случае вы можете использовать:

      var selectedItem by remember{mutableStateOf( "")}
LazyColumn {
    this.items(items = items) {
        Row(modifier = Modifier.selectable(
            selected = selectedItem == it.first,
            onClick = { selectedItem = it.first}
                )
        ) {
            if (selectedItem == it.first) {
                Text(it.first, color = Color.Red)
            } else {
                Text(it.first)
            }
        }
    }
}

Обратите внимание, что в принятом ответе все представления элементов будут перекомпоновываться каждый раз при изменении выбора, потому что лямбды, переданные в onClickа также content(из Row) нестабильны (https://developer.android.com/jetpack/compose/lifecycle#skipping).

Вот один из способов сделать так, чтобы перекомпоновывались только невыбранные и выбранные элементы:

      @Composable
fun ItemView(index: Int, selected: Boolean, onClick: (Int) -> Unit){
    Text(
        text = "Item $index",
        modifier = Modifier
            .clickable {
                onClick.invoke(index)
            }
            .background(if (selected) MaterialTheme.colors.secondary else Color.Transparent)
            .fillMaxWidth()
            .padding(12.dp)
    )
}

@Composable
fun LazyColumnWithSelection(){
    var selectedIndex by remember { mutableStateOf(0) }
    val onItemClick = { index: Int -> selectedIndex = index}
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
    ){
        items(100){ index ->
            ItemView(
                index = index,
                selected = selectedIndex == index,
                onClick = onItemClick
            )
        }
    }
}

Обратите внимание, как аргументы передаются в ItemViewизменяться только для элементов, выбранное состояние которых изменяется. Это потому, что onItemClickлямбда всегда одинакова.

Существует модификатор clickable, который позволяет легко обнаруживать щелчок, а также предоставляет функции доступности и отображает визуальные индикаторы при нажатии (например, рябь).

      @Composable
fun ClickableSample() {
  val count = remember { mutableStateOf(0) }
  // content that you want to make clickable
  Text(
    text = count.value.toString(),
    modifier = Modifier.clickable { count.value += 1 }
  )
}

Для получения дополнительной информации см. https://developer.android.com/jetpack/compose/gestures .

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