sarthak gupta
sarthak gupta

Reputation: 896

Is there any way to make two horizontal pager of accompanist library to work synchronously?

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

Upvotes: 5

Views: 1906

Answers (1)

Phil Dukhov
Phil Dukhov

Reputation: 88072

Using snapshotFlow, it is possible to track changes in the result of a block whose calculations depend on state changes.

Each time a state changes, the flow will emit a new value of the calculation.

In this case, we track both which pager is being scrolled by user by checking isScrollInProgress, and current scroll position by checking properties currentPage and currentPageOffsetFraction properties.

When we have these values emitted, we can scroll the second pager with values from the first one.

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

    // sync both horizontal pagers
    LaunchedEffect(Unit) {
        snapshotFlow {
            val (scrollingState, followingState) = if (firstPagerState.isScrollInProgress) {
                firstPagerState to secondPagerState
            } else if (secondPagerState.isScrollInProgress) {
                secondPagerState to firstPagerState
            } else {
                return@snapshotFlow null
            }
            Triple(followingState, scrollingState.currentPage, scrollingState.currentPageOffsetFraction)
        }
            .filterNotNull()
            .collect { (followingState, currentPage, currentPageOffsetFraction) ->
                followingState.scrollToPage(
                    page = currentPage,
                    pageOffsetFraction = currentPageOffsetFraction
                )
            }
    }

    listOf(firstPagerState, secondPagerState).forEach { state ->
        HorizontalPager(
            state = state,
            modifier = Modifier
                .weight(1f)
        ) {
            Text(
                it.toString(),
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentWidth(Alignment.CenterHorizontally)
            )
        }
    }
}

Result:

Upvotes: 10

Related Questions