Reputation: 3435
LazyColumn
has item keys, in order to tie the item's state to a unique identifier rather than the list index. Is there a way to use item keys in a non-lazy list like this one?
Column {
for (item in list) {
Text(item)
}
}
The reason I ask is because I want to implement SwipeToDismiss
to delete items from a list, which only works if you pass a key to a LazyColumn
(solution), but my list of dismissable items is nested inside of a LazyColumn
, and I can't nest a LazyColumn
inside of another LazyColumn
's itemContent block (Nesting scrollable in the same direction layouts is not allowed):
val items = listOf<String>(...)
val groups = items.groupBy { it.first() }
LazyColumn {
items(groups, { /* key */ }) { (firstChar, group) ->
// not allowed!
LazyColumn {
items(group, { /* key */ }) { item ->
Text(item)
}
}
}
}
I could wrap the items()
call itself in a for loop like this:
val items = listOf<String>(...)
val groups = items.groupBy { it.first() }
LazyColumn {
groups.forEach { (firstChar, group) ->
items(group, { /* key */ }) { item ->
Text(item)
}
}
}
But then state in each of the outer loop's items would be keyed against its index. And I need to provide item keys for groups as well, in order to preserve their state on position changes.
Upvotes: 11
Views: 6754
Reputation: 29575
The general pattern for this is,
for (item in items) {
key(item) {
... // use item
}
}
The key
composable is special and Compose will use item
as a key to detect when the state should move when an the value of item
moves in the items
collection.
Upvotes: 19