4

What I am trying to achieve is if there are two horizontal pagers, then on swiping top one to left then the bottom horizontal pager should swipe to right and vice-versa, have tried using pagerState scrollBy method but not getting desired output

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
sarthak gupta
  • 826
  • 4
  • 12
  • Please share your code where you have tried with `scrollBy` method. – RaBaKa 78 Dec 23 '21 at 07:39
  • I calculated the current Page Item Offset and on the basis of if I scrolled progrmatically but wasnt getting desire output, currenlty dont have the code and implemented how normal pagerWorks – sarthak gupta Dec 23 '21 at 10:07

1 Answers1

5

First of all, you need to determine which pager is scrolled and which one should follow it. This can be done with isScrollInProgress, I use it inside derivedStateOf to avoid unnecessary re-compositions.

Then I run LaunchedEffect. I'm passing pair of pager states in needed order, or null, as a key, so LaunchedEffect will be re-launched when scrolling stops/starts. Using snapshotFlow, it is possible to track changes in the result of a block whose calculations depend on state changes.

PagerState has scroll position information in the properties currentPage and currentPageOffset. scrollToPage takes only 0..1 values for page offset, but currentPageOffset can be less than zero when scrolling backward.

Suppose currentPage = 2 and currentPageOffset = -0.1. In this case, I will get 1.9 in pagePart, and I need to split it back to get 1 and 0.9. To do this I use divideAndRemainder: it will return a list of the form listOf(1.0, 0.9).

Column {
    val count = 10
    val firstPagerState = rememberPagerState()
    val secondPagerState = rememberPagerState()

    val scrollingFollowingPair by remember {
        derivedStateOf {
            if (firstPagerState.isScrollInProgress) {
                firstPagerState to secondPagerState
            } else if (secondPagerState.isScrollInProgress) {
                secondPagerState to firstPagerState
            } else null
        }
    }
    LaunchedEffect(scrollingFollowingPair) {
        val (scrollingState, followingState) = scrollingFollowingPair ?: return@LaunchedEffect
        snapshotFlow { scrollingState.currentPage + scrollingState.currentPageOffset }
            .collect { pagePart ->
                val divideAndRemainder = BigDecimal.valueOf(pagePart.toDouble())
                    .divideAndRemainder(BigDecimal.ONE)

                followingState.scrollToPage(
                    divideAndRemainder[0].toInt(),
                    divideAndRemainder[1].toFloat(),
                )
            }
    }

    HorizontalPager(
        count = count,
        state = firstPagerState,
        modifier = Modifier.weight(1f)
    ) {
        Text(it.toString())
    }
    HorizontalPager(
        count = count,
        state = secondPagerState,
        modifier = Modifier.weight(1f)
    ) {
        Text(it.toString())
    }
}

Result:

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220