Actually the purpose of the Pager is to do this kind of things and it comes with more functionalities you can use and also efficient and easy to implement. But in case if you still want to do same with LazyColumn
then we have to implement our own scrolling behaviour. And, you can done this by following these simple steps:
Step 1: Set userScrollEnabled
to false
so that user cannot do the default scrolling.
Step 2: Pass the state
to the LazyColumn
using rememberLazyListState
by saving it in different variable as we will use it later.
Step 3: Now set the modifier
for drag gestures as shown in the code and then you can try out the feature.
val lazyListState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
var currentIndex = 0
var job: Job? = null
LazyColumn(
state = lazyListState,
userScrollEnabled = false, // to restrict the default scrolling behaviour
modifier = Modifier
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
change.consume()
val (x,y) = dragAmount
// cancelling the previous job
job?.cancel()
job = coroutineScope.launch{
// Waiting for next gesture changes
delay(100)
// Although we don't need right and left swipes
when {
x > 0 -> { /* swiped right */ }
x < 0 -> { /* swiped left */ }
}
when {
y > 0 -> { /* swiped down */
try { lazyListState.animateScrollToItem(--currentIndex) }
catch (e: Exception) { /* handle the error */}
}
y < 0 -> { /* swiped up */
try { lazyListState.animateScrollToItem(++currentIndex) }
catch (e: Exception) { /* handle the error */}
}
}
}
}
}
) {
// List content...
}
NOTE: In this logic the currentIndex
can you beyond the limits but the app will not crashed so you can also handle these edge cases.
You might came up with the question why we have done job assignment and cancellation. So the reason is that the gestures changes multiple time rapidly and due to this it can do multiple scrolling so to counter this we have used Debounce Technique. You can check more about in one of my solution at: https://stackoverflow.com/a/76968173/14972910