如何使 Jetpack Compose HorizontalPager 仅向前滑动(禁用向后滑动)?

问题描述 投票:0回答:1

在使用 Jetpack Compose 的 Android 上,我想让 HorizontalPager 仅向一个方向滚动,因此只能向前滚动。我无法使用

pointerInput
pointerInteropFilter
来正确处理我的手势检测。

我尝试了以下代码,但两个选项都不起作用

 // if you use detectDragGesture on the box, then the message is printed, however the event does not bubble up and the horizontalPager will not swipe
  // if you put the pointerInput onto the HorizontalPager, then the gesture is not detected and no message is printed
  HorizontalPager(state = pagerState) { page ->
        // Display each page with a different background color
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(colors[page])
                .pointerInput(Unit) {
                    detectDragGestures { _, _ ->
                        println("In Here")
                    }
               }
        ) {
        }
   }
   
// the other option is to use pointerInteropFilter 
// the problem with this is that when used with the horizontalPager it does not detect the ACTION_MOVE for horizontal scroll
 HorizontalPager(state = pagerState) { page ->
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(colors[page])
                .pointerInteropFilter { motionEvent ->
                    when (motionEvent.action) 
                        MotionEvent.ACTION_MOVE -> {
                                // This is not detected for horizontal scroll
                            println("ACTION_MOVE")
                        }                    }
                    true
                }
        ) {
            Text("Hello")
        }
    }

如果我可以正确检测到向后滑动,那么我应该能够在寻呼机上设置

userScrollEnabled
以禁用向后滑动。

任何其他禁用向后滑动的方法也可以。

android android-jetpack-compose android-viewpager
1个回答
0
投票

通过使用 PointerEventPass.Initial 手势,您可以在水平滚动之前获取手势,如此处解释。如果

pagerState.currentPageOffsetFraction
低于零,则通过使用事件,您可以防止 HorizontalPager 获取它。

enter image description here

   @Preview
    @Composable
    fun PagerScrollCancelBackwardScroll() {
    
        Column(
            modifier = Modifier.fillMaxSize().padding(16.dp)
        ) {
    
            val pagerState = rememberPagerState {
                5
            }
            
            HorizontalPager(
                modifier = Modifier
                    .pointerInput(Unit) {
                        awaitEachGesture {
                            awaitFirstDown()
    
                            do {
                                val event: PointerEvent = awaitPointerEvent(
                                    pass = PointerEventPass.Initial
                                )
    
                                event.changes.forEach {
                                    val posX = it.position.x - it.previousPosition.x
                                    val currentPageOffsetFraction = pagerState.currentPageOffsetFraction
    
                                    if (currentPageOffsetFraction < 0) {
                                        it.consume()
                                    }
    
                                    println("PosX: $posX, currentPageOffsetFraction: $currentPageOffsetFraction")
    
                                }
    
                            } while (event.changes.any { it.pressed })
                        }
                    },
                state = pagerState,
                pageSpacing = 16.dp,
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(200.dp)
                        .background(Color.LightGray, RoundedCornerShape(16.dp)),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = "Page $it",
                        fontSize = 28.sp
                    )
                }
            }
        }
    }

如果你不想看到过度滚动效果

@Preview
@Composable
fun PagerScrollCancelBackwardScroll() {

    Column(
        modifier = Modifier.fillMaxSize().padding(16.dp)
    ) {

        val pagerState = rememberPagerState {
            5
        }

        HorizontalPager(
            modifier = Modifier
                .pointerInput(Unit) {
                    awaitEachGesture {

                        val currentPageOffsetFraction = pagerState.currentPageOffsetFraction

                        val isBackwardsScroll = currentPageOffsetFraction < 0
                       val down  = awaitFirstDown(
                           pass = PointerEventPass.Initial
                       )

                        if (isBackwardsScroll){
                            down.consume()
                        }

                        do {
                            val event: PointerEvent = awaitPointerEvent(
                                pass = PointerEventPass.Initial
                            )

                            event.changes.forEach {

                                if (isBackwardsScroll) {
                                    it.consume()
                                }
                            }

                        } while (event.changes.any { it.pressed })
                    }
                },
            state = pagerState,
            pageSpacing = 16.dp,
        ) {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(200.dp)
                    .background(Color.LightGray, RoundedCornerShape(16.dp)),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = "Page $it",
                    fontSize = 28.sp
                )
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.