Как правильно подойти к вопросу: compose: как отобразить mutable список из mutable объектов?

Ссылка скопирована
1 ответ

Изучаю Compose

По вводным: загружаю по api список заказов - обычныe POJO
По вводным: далее я отображаю его в LazyColumn

Далее список может меняться, и нужно все это отобразить.
По вводным: тут вроде все просто - делаем mutableListOf - и compose сам все отрисует
По вводным: но помимо списка, может меняться и сам заказ (например, фоновая служба может изменить его статус)

Нужно понять: и вот как отрисовать это изменение?
Нужно понять: на ум приходят либо использовать key либо заворачивать каждый параметр заказа в mutable переменную, но может есть более принятый способ?

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Ирина WP Ответ

В Jetpack Compose mutable список из mutable объектов часто не перерисовывается, потому что Compose отслеживает изменения состояния, а не произвольные мутации внутри обычного объекта. Если вы меняете поле объекта внутри списка, но ссылка на список и объект остаётся той же, Compose может не понять, что нужно обновить UI.

Лучший путь — делать состояние иммутабельным: хранить список data class и при изменении создавать новый список с изменённым элементом.

data class Item(
    val id: Int,
    val title: String,
    val checked: Boolean
)
 
var items by mutableStateOf(listOf<Item>())
 
fun toggle(id: Int) {
    items = items.map { item ->
        if (item.id == id) item.copy(checked = !item.checked) else item
    }
}

data class Item( val id: Int, val title: String, val checked: Boolean ) var items by mutableStateOf(listOf<Item>()) fun toggle(id: Int) { items = items.map { item -> if (item.id == id) item.copy(checked = !item.checked) else item } }

Если нужен изменяемый список, используйте mutableStateListOf, но всё равно лучше заменять элемент целиком:

val items = mutableStateListOf<Item>()
 
fun update(index: Int) {
    items[index] = items[index].copy(checked = true)
}

val items = mutableStateListOf<Item>() fun update(index: Int) { items[index] = items[index].copy(checked = true) }

Плохой вариант:

items[index].checked = true

items[index].checked = true

Если checked — обычное поле, Compose не увидит изменение. Можно делать поля как mutableStateOf внутри объекта, но это усложняет модель и часто хуже для поддержки.

В LazyColumn обязательно задавайте стабильный key:

LazyColumn {
    items(items, key = { it.id }) { item ->
        RowItem(item)
    }
}

LazyColumn { items(items, key = { it.id }) { item -> RowItem(item) } }

Итог: не мутируйте обычные поля объектов внутри списка. Используйте immutable data class + copy или mutableStateListOf с заменой элемента. Так Compose стабильно увидит изменение и перерисует нужную строку.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно