diff --git a/pager/src/main/java/com/google/accompanist/pager/Pager.kt b/pager/src/main/java/com/google/accompanist/pager/Pager.kt index 0dac998dc..7b283cef8 100644 --- a/pager/src/main/java/com/google/accompanist/pager/Pager.kt +++ b/pager/src/main/java/com/google/accompanist/pager/Pager.kt @@ -385,6 +385,7 @@ internal fun Pager( ConsumeFlingNestedScrollConnection( consumeHorizontal = !isVertical, consumeVertical = isVertical, + pagerState = state, ) } @@ -449,9 +450,11 @@ internal fun Pager( } } +@OptIn(ExperimentalPagerApi::class) private class ConsumeFlingNestedScrollConnection( private val consumeHorizontal: Boolean, private val consumeVertical: Boolean, + private val pagerState: PagerState, ) : NestedScrollConnection { override fun onPostScroll( consumed: Offset, @@ -465,9 +468,15 @@ private class ConsumeFlingNestedScrollConnection( } override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { - // We can consume all post fling velocity on the main-axis - // so that it doesn't propagate up to the Pager - return available.consume(consumeHorizontal, consumeVertical) + return if (pagerState.currentPageOffset != 0f) { + // The Pager is already scrolling. This means that a nested scroll child was + // scrolled to end, and the Pager can use this fling + Velocity.Zero + } else { + // A nested scroll child is still scrolling. We can consume all post fling + // velocity on the main-axis so that it doesn't propagate up to the Pager + available.consume(consumeHorizontal, consumeVertical) + } } } diff --git a/pager/src/sharedTest/kotlin/com/google/accompanist/pager/HorizontalPagerScrollingContentTest.kt b/pager/src/sharedTest/kotlin/com/google/accompanist/pager/HorizontalPagerScrollingContentTest.kt index 4cea9e9b8..97779915c 100644 --- a/pager/src/sharedTest/kotlin/com/google/accompanist/pager/HorizontalPagerScrollingContentTest.kt +++ b/pager/src/sharedTest/kotlin/com/google/accompanist/pager/HorizontalPagerScrollingContentTest.kt @@ -89,6 +89,17 @@ class HorizontalPagerScrollingContentTest { // Assert that we're still on page 0 assertThat(pagerState.currentPage).isEqualTo(0) assertThat(pagerState.currentPageOffset).isWithin(0.01f).of(0f) + + // Perform a scroll in the same direction again + rule.onNodeWithTag(TestTag) + .swipeAcrossCenterWithVelocity(velocityPerSec = 2_000.dp, distancePercentageX = -0.5f) + + // Wait for the flings to end + rule.waitForIdle() + + // Assert that we're now on page 1 + assertThat(pagerState.currentPage).isEqualTo(1) + assertThat(pagerState.currentPageOffset).isWithin(0.01f).of(0f) } companion object { diff --git a/pager/src/sharedTest/kotlin/com/google/accompanist/pager/VerticalPagerScrollingContentTest.kt b/pager/src/sharedTest/kotlin/com/google/accompanist/pager/VerticalPagerScrollingContentTest.kt index f482fb85e..0328f3cf3 100644 --- a/pager/src/sharedTest/kotlin/com/google/accompanist/pager/VerticalPagerScrollingContentTest.kt +++ b/pager/src/sharedTest/kotlin/com/google/accompanist/pager/VerticalPagerScrollingContentTest.kt @@ -88,6 +88,17 @@ class VerticalPagerScrollingContentTest { // Assert that we're still on page 0 assertThat(pagerState.currentPage).isEqualTo(0) assertThat(pagerState.currentPageOffset).isWithin(0.01f).of(0f) + + // Perform a scroll in the same direction again + rule.onNodeWithTag(TestTag) + .swipeAcrossCenterWithVelocity(velocityPerSec = 2_000.dp, distancePercentageY = -0.5f) + + // Wait for the flings to end + rule.waitForIdle() + + // Assert that we're now on page 1 + assertThat(pagerState.currentPage).isEqualTo(1) + assertThat(pagerState.currentPageOffset).isWithin(0.01f).of(0f) } companion object {