Improve pager gesture handling (again)
This commit is contained in:
parent
d1218e8d2e
commit
3759a99510
@ -667,37 +667,34 @@ fun Modifier.pagerScaffoldScrollHandler(
|
|||||||
|
|
||||||
awaitEachGesture {
|
awaitEachGesture {
|
||||||
var overSlop = false
|
var overSlop = false
|
||||||
var lockedInScroll = disablePager
|
val initialDown =
|
||||||
val initialDown = awaitFirstDown(requireUnconsumed = false, pass = PointerEventPass.Initial)
|
awaitFirstDown(requireUnconsumed = false, pass = PointerEventPass.Initial)
|
||||||
val down = if (scrollableState.isScrollInProgress || pagerState.isScrollInProgress) {
|
val down =
|
||||||
overSlop = true
|
if (scrollableState.isScrollInProgress || pagerState.isScrollInProgress) {
|
||||||
scope.launch {
|
overSlop = true
|
||||||
scrollableState.scrollBy(0f)
|
scope.launch {
|
||||||
pagerState.scrollBy(0f)
|
scrollableState.scrollBy(0f)
|
||||||
|
pagerState.scrollBy(0f)
|
||||||
|
}
|
||||||
|
initialDown
|
||||||
|
} else {
|
||||||
|
awaitFirstDown(requireUnconsumed = false)
|
||||||
}
|
}
|
||||||
initialDown
|
|
||||||
} else {
|
|
||||||
awaitFirstDown(requireUnconsumed = false)
|
|
||||||
}
|
|
||||||
velocityTracker.resetTracking()
|
velocityTracker.resetTracking()
|
||||||
velocityTracker.addPointerInputChange(down)
|
velocityTracker.addPointerInputChange(down)
|
||||||
val notCanceled = drag(down.id) {
|
val canceled = !drag(down.id) {
|
||||||
if (it.isConsumed) return@drag
|
if (it.isConsumed) return@drag
|
||||||
val totalDrag = down.position - it.position
|
val totalDrag = down.position - it.position
|
||||||
if (!lockedInScroll && totalDrag.y.absoluteValue > lockScrollThreshold) {
|
if (!overSlop && totalDrag.getDistanceSquared() > touchSlopSq) {
|
||||||
lockedInScroll = true
|
|
||||||
scope.launch {
|
|
||||||
pagerState.animateScrollToPage(pagerState.settledPage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!lockedInScroll && !overSlop && totalDrag.getDistanceSquared() > touchSlopSq) {
|
|
||||||
overSlop = true
|
overSlop = true
|
||||||
}
|
}
|
||||||
if (!overSlop) return@drag
|
if (!overSlop) return@drag
|
||||||
val dragAmount = it
|
val dragAmount = it
|
||||||
.positionChange()
|
.positionChange()
|
||||||
.let {
|
.let {
|
||||||
if (!overSlop || lockedInScroll) it.copy(x = 0f) else it
|
if (it.x.absoluteValue > it.y.absoluteValue) it.copy(y = 0f) else it.copy(
|
||||||
|
x = 0f
|
||||||
|
)
|
||||||
}
|
}
|
||||||
it.consume()
|
it.consume()
|
||||||
velocityTracker.addPointerInputChange(it)
|
velocityTracker.addPointerInputChange(it)
|
||||||
@ -707,11 +704,11 @@ fun Modifier.pagerScaffoldScrollHandler(
|
|||||||
NestedScrollSource.Drag
|
NestedScrollSource.Drag
|
||||||
)
|
)
|
||||||
val available = dragAmount - preConsumed
|
val available = dragAmount - preConsumed
|
||||||
val consumedY = scrollableState.scrollBy(available.y * scrollMultiplier) * scrollMultiplier
|
val consumedY =
|
||||||
val consumedX = if (!lockedInScroll) {
|
scrollableState.scrollBy(available.y * scrollMultiplier) * scrollMultiplier
|
||||||
pagerState.scrollBy(available.x * pagerMultiplier) * pagerMultiplier
|
val consumedX = pagerState.scrollBy(available.x * pagerMultiplier) * -1f
|
||||||
} else available.x
|
val totalConsumed =
|
||||||
val totalConsumed = Offset(preConsumed.x + consumedX, preConsumed.y + consumedY)
|
Offset(preConsumed.x + consumedX, preConsumed.y + consumedY)
|
||||||
nestedScrollDispatcher.dispatchPostScroll(
|
nestedScrollDispatcher.dispatchPostScroll(
|
||||||
totalConsumed,
|
totalConsumed,
|
||||||
dragAmount - totalConsumed,
|
dragAmount - totalConsumed,
|
||||||
@ -719,51 +716,50 @@ fun Modifier.pagerScaffoldScrollHandler(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (notCanceled) {
|
val velocity = velocityTracker
|
||||||
val velocity = velocityTracker
|
.calculateVelocity()
|
||||||
.calculateVelocity()
|
|
||||||
|
|
||||||
if (velocity.x.absoluteValue > velocity.y.absoluteValue && !lockedInScroll) {
|
if (canceled || velocity.x.absoluteValue > velocity.y.absoluteValue) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val preConsumed = nestedScrollDispatcher.dispatchPreFling(velocity)
|
val preConsumed = nestedScrollDispatcher.dispatchPreFling(velocity)
|
||||||
val flingVelocity = (velocity - preConsumed).x
|
val flingVelocity = (velocity - preConsumed).x
|
||||||
|
|
||||||
if (flingVelocity.absoluteValue > 400.dp.toPx()) {
|
if (flingVelocity.absoluteValue > 400.dp.toPx()) {
|
||||||
if (flingVelocity * pagerMultiplier < 0) {
|
if (flingVelocity * pagerMultiplier < 0) {
|
||||||
pagerState.animateScrollToPage(pagerState.settledPage - 1)
|
pagerState.animateScrollToPage(pagerState.settledPage - 1)
|
||||||
} else {
|
|
||||||
pagerState.animateScrollToPage(pagerState.settledPage + 1)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
pagerState.animateScrollToPage(pagerState.settledPage)
|
pagerState.animateScrollToPage(pagerState.settledPage + 1)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pagerState.animateScrollToPage(pagerState.settledPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
nestedScrollDispatcher.dispatchPostFling(
|
||||||
|
velocity,
|
||||||
|
Velocity.Zero,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scope.launch {
|
||||||
|
val preConsumed = nestedScrollDispatcher.dispatchPreFling(velocity)
|
||||||
|
val flingVelocity = (velocity - preConsumed).y
|
||||||
|
var consumed = 0f
|
||||||
|
launch {
|
||||||
|
with(flingBehavior) {
|
||||||
|
scrollableState.scroll {
|
||||||
|
consumed =
|
||||||
|
performFling(flingVelocity * scrollMultiplier) * scrollMultiplier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val totalConsumed =
|
||||||
|
Velocity(preConsumed.x, preConsumed.y + consumed)
|
||||||
nestedScrollDispatcher.dispatchPostFling(
|
nestedScrollDispatcher.dispatchPostFling(
|
||||||
velocity,
|
totalConsumed,
|
||||||
Velocity.Zero,
|
velocity - totalConsumed
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
launch {
|
||||||
scope.launch {
|
pagerState.animateScrollToPage(pagerState.settledPage)
|
||||||
val preConsumed = nestedScrollDispatcher.dispatchPreFling(velocity)
|
|
||||||
val flingVelocity = (velocity - preConsumed).y
|
|
||||||
var consumed = 0f
|
|
||||||
launch {
|
|
||||||
with(flingBehavior) {
|
|
||||||
scrollableState.scroll {
|
|
||||||
consumed = performFling(flingVelocity * scrollMultiplier) * scrollMultiplier
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val totalConsumed =
|
|
||||||
Velocity(preConsumed.x, preConsumed.y + consumed)
|
|
||||||
nestedScrollDispatcher.dispatchPostFling(
|
|
||||||
totalConsumed,
|
|
||||||
velocity - totalConsumed
|
|
||||||
)
|
|
||||||
}
|
|
||||||
launch {
|
|
||||||
pagerState.animateScrollToPage(pagerState.settledPage)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user