androidkotlinandroid-jetpack-composeandroid-jetpack

In Jetpack Compose, how can I prevent HorizontalPager from scrolling when swiping left or right on the edge of the screen?


I've created a HorizontalPager with a width that matches the screen. However, I've noticed that when I use the edge swipe gesture on the phone to go back to the previous screen, it momentarily causes the HorizontalPager to scroll. This provides a very poor user experience. How can I prevent it from moving?

this is my image

Image Example

I want the HorizontalPager to not scroll when swiping from the edge of the screen. I've noticed that other apps don't have this issue, though they might not be written with Compose.

this is my code,I use Samsung galaxy s24

val pagerState = rememberPagerState(initialPage = 0, pageCount = { 2 })
    val pagerStateInner = rememberPagerState(initialPage = 0, pageCount = { 3 })
    HorizontalPager(
        state = pagerState,
        userScrollEnabled = true,
    ) { pageOut ->
        if (pageOut == 0) {
            HorizontalPager(
                state = pagerStateInner,
                userScrollEnabled = true,
            ) { pageInner ->
                Column(
                    modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Gray),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.Center
                ) {
                    Text(
                        text = "this inner ${pageInner}"
                    )
                }
            }
        } else {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Blue),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center
            ) {
                Text(
                    text = "this out ${pageOut}"
                )
            }
        }

    }

Solution

  • You can using a custom Modifier

    fun Modifier.ignoreEdgeSwipe(edgeWidth: Dp = 32.dp): Modifier = composed {
        val edgeWidthPx = with(LocalDensity.current) { edgeWidth.toPx() }
        pointerInput(Unit) {
            awaitEachGesture {
                val down = awaitPointerEventScope { awaitFirstDown() }
                
                if (down.position.x < edgeWidthPx || down.position.x > size.width - edgeWidthPx) {
                    return@awaitEachGesture
                }
            }
        }
    }
    
    

    and use it in HorizontalPager like this

    HorizontalPager(
        state = pagerState,
        userScrollEnabled = true,
        modifier = Modifier
            .fillMaxSize()
            .ignoreEdgeSwipe()  //===> this new line
    ) { pageOut ->
     
    }