I want to make some item swap mechanism in LazyColumn items. For this I have used itemIndexed but after a swipe, index numbers becomes the same. For example if I swap first item with second the item index for both become 0. I suspect this behavior because of reuse of component in LazyColumn.
@Composable
fun Screen(modifier:Modifier = Modifier) {
val itemList = remember { mutableStateListOf("Item 1", "Item 2", "Item 3", "Item 4") }
val context = LocalContext.current
LazyColumn(modifier = modifier) {
itemsIndexed(itemList, key = { _, text -> text }) { index, text ->
Card(
modifier = Modifier
.pointerInput(Unit) {
detectTapGestures(
onTap = {
Toast.makeText(context, "" + index, Toast.LENGTH_SHORT).show()
},
onDoubleTap = {
Collections.swap(itemList, index, index + 1)
}
)
}
.padding(8.dp)
.fillMaxWidth()
.animateItem()
) {
Row(
modifier = Modifier.padding(16.dp).fillMaxSize()
) {
Text("$index. $text")
}
}
}
}
}
In this example I can tap to look index number of the item and double tap on a item to swap with bottom item.
Test : If I click on first item it toast 0 and second item toast 1. Now when I double tap on the first item or second item and then do the same both toast 0. But the Text displaying correct indexes in both cases.
I came up with solution but it is very inefficient nor feels the right way. Which is declaring variable index inside items and reassign it before the Text with the index for itemIndexed (notice the lambda parameter index change to i). But multiple recompsitions happens this.
@Composable
fun Screen(modifier:Modifier = Modifier) {
...
LazyColumn(modifier = modifier) {
itemsIndexed(...) { i/*index change to i*/, text ->
// New Index declaration
var index by remember { mutableIntStateOf(i) }
Card(...) {
Row(
modifier = Modifier.padding(16.dp).fillMaxSize()
) {
index = i // Reassigns here
Text("$index. $text")
}
}
}
}
}
Any help is appreciated.