androidandroid-viewpagerandroid-jetpack-composejetpack-compose-accompanist

Swipe sensitivity for HorizontalPager in Compose


I implemented a simple HorizontalPager which works mostly as expected. The app I develop is for one specific device, a 8" Tablet in landscape mode. At the moment it is required to swipe more than 50% of the screen-width to get to the next/prev page. This is a very long swipe and I would like to reduce that to make changing pages easier...

I played around with fling behavior and tried to manually change pages when the offset changed or to intercept the touchevents...Nothing really lead to the desired behavior.

Since the "problem" seems so simple, I really hope that I have just overseen something. Do you have an idea what I could try?


Solution

  • This solved my problem, you can edit minFlingDistanceDp to change the sensitivity:

    HorizontalPager(
                modifier = Modifier.fillMaxSize(),
                state = pagerState,
                count = noOfPages,
                flingBehavior = flingBehavior(pagerState = pagerState, noOfPages = noOfPages)
            ) { page ->
                //Content
            }
    
    
    val minFlingDistanceDp = 150.dp
    
    @OptIn(ExperimentalPagerApi::class, dev.chrisbanes.snapper.ExperimentalSnapperApi::class)
    @Composable
    fun flingBehavior(pagerState: PagerState, noOfPages: Int): FlingBehavior {
        var currentPageIndex = remember { pagerState.currentPage }
        return PagerDefaults.flingBehavior(
            state = pagerState,
            snapIndex = { layoutInfo, _, _ ->
                val distanceToStartSnap = layoutInfo.distanceToIndexSnap(currentPageIndex)
                currentPageIndex = when {
                    distanceToStartSnap < -(minFlingDistanceDp.value) -> {
                        (currentPageIndex + 1).coerceAtMost(noOfPages - 1)
                    }
                    distanceToStartSnap > minFlingDistanceDp.value -> {
                        (currentPageIndex - 1).coerceAtLeast(0)
                    }
                    else -> {
                        currentPageIndex
                    }
                }
                currentPageIndex
            }
        )
    }