1

I want to create the reels feature with the lazy columns in kotlin where user can scroll the single item at a time not the multiple one's.

I tried to use the

   flingBehavior = rememberSnapFlingBehavior(
                snapLayoutInfoProvider = SnapLayoutInfoProvider(state)
            )

this code can snap the item but can't stop the user from scrolling multiple items at a time I tried to use the pager but the pager performance is not as much good as the lazy columns.

Anas Mirza
  • 13
  • 3

1 Answers1

0

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

Atul Sharma
  • 399
  • 3
  • 12
  • Thanks for the answer, but I need the smooth scroll behaviour like the ViewPager2. I don't want to block the user interaction. – Anas Mirza Sep 01 '23 at 10:17
  • @AnasMirza And that's what I was saying that Pager library comes with great functionalities and is also performance efficient so if you want exact same functionality like pager then you should implement the same as the `LazyColumn` will work with it's own efficiency. – Atul Sharma Sep 01 '23 at 10:22
  • Thanks, Just one more thing to confirm: Can the pager manage a large amount of data like the viewPager2 or lazyColumn? – Anas Mirza Sep 02 '23 at 20:35