在使用 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
以禁用向后滑动。
任何其他禁用向后滑动的方法也可以。
通过使用 PointerEventPass.Initial 手势,您可以在水平滚动之前获取手势,如此处解释。如果
pagerState.currentPageOffsetFraction
低于零,则通过使用事件,您可以防止 HorizontalPager 获取它。
@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
)
}
}
}
}