Если коротко, то key в LazyColumn/LazyRow нужен, чтобы Compose понимал, какой элемент списка “кто есть кто” при вставках/удалениях/перестановках.
Без правильных ключей начинают прыгать remember-состояния, анимации, фокус и т.п.
Что делает key в LazyColumn/LazyRow
key — это уникальный идентификатор элемента в пределах списка. Compose использует его, чтобы:
- Понимать, что элемент с id=5 — это тот же элемент, что и раньше, только, например, сдвинулся на другую позицию.
- Переиспользовать слоты / состояние / анимации именно этого элемента, а не рандомно(!).
LazyColumn {
items(
items = users,
key = { user -> user.id } // вот тут
) { user ->
UserRow(user)
}
}
// Или
LazyColumn {
items(users, key = { it.id }) { user -> ... }
}
Ключ должен быть:
- Стабильным — не меняться для одного и того же логического элемента (например,
user.id). - Уникальным среди элементов — иначе Compose будет путать.
Идеальный кандидатом может быть id из модели (id: Long, UUID, String, и т.п.).
Обязательно (или очень желательно) использовать key, когда:
- список меняется: элементы добавляются/удаляются/переставляются
- у элемента есть внутреннее состояние:
rememberrememberSaveable- анимации (
animate*AsState,AnimatedVisibility) - фокус (TextField внутри)
Что будет, если key не задать?
Если key не указан, то LazyColumn по умолчанию использует индекс элемента в списке как ключ. И это ломает консистентность UI, когда нужно отсортировать-переставить список, вставить элемент в начало/середину, удалить элемент.
Пример:
//Было
index: 0 1 2
user: A B C
key: 0 1 2
//Стало (вставили нового пользователя D в начало)
index: 0 1 2 3
user: D A B C
key: 0 1 2 3
С точки зрения Compose: «старый A с key=0» => теперь это «D с key=0», «старый B с key=1» => «теперь A с key=1».
И результате получаем:
rememberвнутри айтема начинает «переезжать» с одного пользователя на другого- скролл может дергаться при сложных обновлениях
- анимации/фокус/selection «перескакивают»
Когда key не обязателен
Можно НЕ заморачиваться с key, если:
- список не меняет порядок, только полностью заменяется (
items(newList)без insert/remove в середине) - элементы простые, без локального
remember(простоText,Iconи т.п.) - список маленький и статичный (меню настроек, список из 3–5 пунктов, редко меняется)
Но даже там не навредит указать key = id, если он всё равно есть.