I have a LazyColumn
with some items where you can only remove the first item in the list (index 0).
The LazyColumn
looks something like this:
LazyColumn {
itemsIndexed(items, key = { _, item -> item.id }) { index, item ->
val dismissState = rememberDismissState(DismissValue.Default) { dismissValue ->
if (index != 0 && dismissValue == DismissValue.DismissedToEnd) {
someOtherStuff()
false
} else true
}
if (dismissState.isDismissed(DismissDirection.StartToEnd)) {
delete(item)
}
MyItem(dismissState)
}
}
The operation of delete()
is fairly irrelevant, all you have to know is that it removes the list item from the room database table, which is observed by the ViewModel, thus making items
smaller by one element.
The problem is, however, that index
(and lastIndex) inside the rememberDismissState
is not up-to-date with the actual index of the itemsIndexed
. If I remove the first item in a list of 3 items, I won't be able to remove the first item again in the resulting list of two items, because the index of the new first item is still 1
(or so rememberDismissState
thinks).
I know that most likely this has something to do with the rememberDismissState
not being recalculated when the list changes, so how do I do that? A workaround would be to map the list to indices before putting it into itemsIndexed
, but is there any way to make the code above "work properly"?
After coming back to this problem a few months later, I realized the issue:
The rememberDismissState
"remembers" the list state and does not recompute even when the list changes. Since I need this to happen to calculate index
or items.size
, I fixed it by converting rememberDismissState
into a keyed remember, like such:
val dismissState = remember(items) { DismissState(DismissValue.Default) {...} }
Thus, the dismissState is also recalculated each time the list changes, which was needed for me to get the code in my initial question working.
Additionally you could use derivedStateOf
as described here, but as discussed in that answer, semantically there is no difference.