aclassen / ComposeReorderable

Enables reordering by drag and drop in Jetpack Compose (Desktop) LazyList & LazyGrid.
Apache License 2.0
821 stars 86 forks source link

Index out of bounds when multiple items in lazy column #225

Closed ShayDeeJay closed 1 year ago

ShayDeeJay commented 1 year ago

App causes index out of bounds when there are multiple items in a lazy column and the reorderable object tries to scroll out of the item its currently in.

sschendel commented 1 year ago

This appears to be an issue for me in 0.9.6. I'm generally getting IOOB exceptions when I include any item before the items configured as reorderable when onMove callback occurs.

e.g.

val data = remember { mutableStateOf(emptyList<TodoInfo>()) }
data.value = todoList
val state = rememberReorderableLazyListState(
    onMove = { from, to ->
        data.value = data.value.toMutableList().apply {
            // Exception here, no exception if I remove the "header" item 
            add(to.index, removeAt(from.index))  
        }
    },
    onDragEnd = { from, to ->
        onReorder(data.value, to, from)
    }
)

LazyColumn(
    state = state.listState,
    modifier = Modifier
        .reorderable(state)
) {
    item {
        Text(text = "header")
    }
    items(items = data.value, { it.id ?: "" }) { item ->
        ReorderableItem(
            reorderableState = state,
            key = item.id ?: ""
        ) { isDragging->
            val elevation = animateDpAsState(if (isDragging) 16.dp else 0.dp)
            Column(modifier = Modifier
                .shadow(elevation.value)
                .detectReorderAfterLongPress(state)
            ) {
                TodoItemControl(
                    item = item,
                    onToggleDoneClick = onToggleDoneClickItem,
                    onLongClick = onLongPressedItem,
                    onClick = onClickItem
                )
            }

        }
    }
}
sschendel commented 1 year ago

Disregard. I see my problem. Attempting to mutate list by index rather than by key onMove (as the included example with static header/footer does).

Monabr commented 1 year ago

@sschendel @ShayDeeJay Hi. What is the solution for this problem?

sschendel commented 1 year ago

@Monabr the key is at this line. The onMove method is using ItemPosition.key not index.

https://github.com/aclassen/ComposeReorderable/blob/main/android/src/main/kotlin/org/burnoutcrew/android/ui/reorderlist/ImageListViewModel.kt#L32

tudor07 commented 1 year ago

For me that still did not work. It threw IOOB even user tried to drag the item outside of the view. I just added a check that indexes are valid.