Составьте 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 .