1

The Accompanist Pager documentation suggests reacting to page changes as follows :

val pagerState = rememberPagerState()

LaunchedEffect(pagerState) {
    // Collect from the pager state a snapshotFlow reading the currentPage
    snapshotFlow { pagerState.currentPage }.collect { page ->
        AnalyticsService.sendPageSelectedEvent(page)
    }
}

VerticalPager(
    count = 10,
    state = pagerState,
) { page ->
    Text(text = "Page: $page")
}

How can we distinguish scrolling to a page from user gesture, and scrolling to a page using animateScrollingToPage() / scrollingToPage() ? I would like to perform a certain action only on user scroll, not on programmatic scroll.

J. Doe
  • 85
  • 12

2 Answers2

0

Did you try :

val isScrollInProgressFlow = snapshotFlow { pagerState.isScrollInProgress }
Jéwôm'
  • 3,753
  • 5
  • 40
  • 73
0

I had a similar problem and I solved it using interactionsSource. No interaction is emitted when automatic scroll happens. But it emits interactions on user actions.

You can also use other interaction source types.

LaunchedEffect(Unit) {
    pagerState.interactionSource.interactions
        .collect {
            if (it is DragInteraction.Start) {
                Log.d("test", "User interaction is started")
            }
        }
}

In my case I had to cancel automatic scroll on user drag. The simplified version looks like this:

LaunchedEffect(Unit) {

    val autoscrollJob = launch {
        while(true) {
            yield() // exit the coroutine if the job is completed
            delay(autoScrollDelay)
            animateScrollToPage(
                page = (currentPage + 1) % pageCount
            )
        }
    }

    launch {
        interactionSource.interactions
            .collect {
                if (it is DragInteraction.Start) {
                    autoscrollJob.cancel()
                }
            }
    }
}
iamoem
  • 1
  • 1