I have a simple example app that can
If I
It will crash as shown in the GIF below (You can get the code design from here https://github.com/elye/issue_android_jetpack_compose_swipe_to_dismiss_different_data_same_id)
The reason is crashes because, upon Swipe-to-Dismiss the 2 item (of the 2nd time loaded data), the item it found is still the 2 item of the 1st time loaded data.
It does seems dismissState (as shown code below) always remember the 1st time loaded data (instead of the new data loaded)
val dismissState = rememberDismissState(
confirmStateChange = {
Log.d("Track", "$item\n${myListState.value.toMutableList()}")
viewModel.removeItem(item)
true
}
)
Hence this causes the deletion to send the wrong item in for deletion, and thus causes the failure and crash.
The complete LazyColumn and SwipeToDismiss code is as below
LazyColumn(modifier = Modifier.fillMaxHeight()) {
items(
items = myListState.value,
key = { todoItem -> todoItem.id }
) { item ->
val dismissState = rememberDismissState(
confirmStateChange = {
viewModel.removeItem(item)
true
}
)
SwipeToDismiss(
state = dismissState,
background = {
dismissState.dismissDirection ?: return@SwipeToDismiss
Box(modifier = Modifier.fillMaxSize().background(Color.Red))
},
dismissContent = {
// The row view of each item
}
)
}
}
Is this
key = { todoItem -> todoItem.id }
with key = { todoItem -> todoItem.title }
, then it will all be goodrememberDismissState()
will remember the confirmStateChange
lambda, which is part of the DismissState
. In your case, item
can change, but the lambda only captures the initial item
value, leading to the crash.
You can use rememberUpdatedState
to solve this:
val currentItem by rememberUpdatedState(item)
val dismissState = rememberDismissState(
confirmStateChange = {
viewModel.removeItem(currentItem)
true
}
)