A Jetpack Compose (Android) library that enables reordering by drag-and-drop in LazyLists and LazyGrids with smooth animations.
Created by Asadullah Hil Galib.
202511020424.1.1.mp4
- Reorderable LazyColumn and LazyRow
- Reorderable LazyVerticalGrid and LazyHorizontalGrid
- Supports drag handles, animations, and custom styling
- Simple and lightweight, built for Jetpack Compose Material3
Add the library to your project:
dependencies {
implementation("com.github.codergalib2005:compose-reorderable:<latest_version>")
}settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven("https://jitpack.io") // π Add this line
}
}For LazyList:
val state = rememberReorderableLazyListState(onMove = { from, to ->
data.value = data.value.toMutableList().apply {
add(to.index, removeAt(from.index))
}
})val state = rememberReorderableLazyGridState(
onMove = { from, to ->
data.value = data.value.toMutableList().apply {
add(to.index, removeAt(from.index))
}
}
)@Composable
fun VerticalReorderList() {
val data = remember { mutableStateOf(List(100) { "Item $it" }) }
val state = rememberReorderableLazyListState(onMove = { from, to ->
data.value = data.value.toMutableList().apply {
add(to.index, removeAt(from.index))
}
})
LazyColumn(
state = state.listState,
modifier = Modifier
.reorderable(state)
.detectReorderAfterLongPress(state)
) {
items(data.value, { it }) { item ->
ReorderableItem(state, key = item) { isDragging ->
val elevation = animateDpAsState(if (isDragging) 16.dp else 0.dp)
Column(
modifier = Modifier
.shadow(elevation.value)
.background(MaterialTheme.colorScheme.surface)
) {
Text(item)
}
}
}
}
}@Composable
fun VerticalReorderGrid() {
val data = remember { mutableStateOf(List(100) { "Item $it" }) }
val state = rememberReorderableLazyGridState(
dragCancelledAnimation = NoDragCancelledAnimation(),
onMove = { from, to ->
data.value = data.value.toMutableList().apply {
add(to.index, removeAt(from.index))
}
}
)
LazyVerticalGrid(
columns = GridCells.Fixed(4),
state = state.gridState,
modifier = Modifier.reorderable(state)
) {
items(data.value, { it }) { item ->
ReorderableItem(state, key = item, defaultDraggingModifier = Modifier) { isDragging ->
Box(
modifier = Modifier
.aspectRatio(1f)
.background(MaterialTheme.colorScheme.surface)
) {
Text(
text = item,
modifier = Modifier.detectReorderAfterLongPress(state)
)
}
}
}
}
}@Composable
fun HorizontalReorderList() {
val data = remember { mutableStateOf(List(100) { "Item $it" }) }
val state = rememberReorderableLazyListState(onMove = { from, to ->
data.value = data.value.toMutableList().apply {
add(to.index, removeAt(from.index))
}
})
LazyRow(
state = state.listState,
modifier = Modifier
.reorderable(state)
.detectReorderAfterLongPress(state)
) {
items(data.value, { it }) { item ->
ReorderableItem(state, key = item) { isDragging ->
val elevation = animateDpAsState(if (isDragging) 16.dp else 0.dp)
Column(
modifier = Modifier
.shadow(elevation.value)
.background(MaterialTheme.colorScheme.surface)
.padding(8.dp)
) {
Text(item)
}
}
}
}
}@Composable
fun HorizontalReorderGrid() {
val data = remember { mutableStateOf(List(100) { "Item $it" }) }
val state = rememberReorderableLazyGridState(
dragCancelledAnimation = NoDragCancelledAnimation(),
onMove = { from, to ->
data.value = data.value.toMutableList().apply {
add(to.index, removeAt(from.index))
}
}
)
LazyHorizontalGrid(
rows = GridCells.Fixed(2),
state = state.gridState,
modifier = Modifier.reorderable(state)
) {
items(data.value, { it }) { item ->
ReorderableItem(state, key = item, defaultDraggingModifier = Modifier) { isDragging ->
Box(
modifier = Modifier
.aspectRatio(1f)
.background(MaterialTheme.colorScheme.surface)
.padding(4.dp)
) {
Text(
text = item,
modifier = Modifier.detectReorderAfterLongPress(state)
)
}
}
}
}
}- First visible item may not animate β this is a known issue.
- Drag handle and animation can be customized using detectReorder and defaultDraggingModifier.
- Works with Jetpack Compose Material3 theme.
- Supports keyed and indexed-only lists (animated items only work with keyed lists).
GitHub: https://github.com/codergalib2005
YouTube: https://www.youtube.com/@devgalib
Copyright 2025 Asadullah Hil Galib
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.