Skip to content

Commit

Permalink
Merge pull request #1332 from wcaokaze/pager/fix/flinging-nestedscrol…
Browse files Browse the repository at this point in the history
…l-child

[Pager] Make Pager able to scroll by flinging a nested scroll child
  • Loading branch information
Levi-Moreira committed Nov 2, 2022
2 parents 916e1bb + 54fe52a commit 9706080
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
15 changes: 12 additions & 3 deletions pager/src/main/java/com/google/accompanist/pager/Pager.kt
Expand Up @@ -366,6 +366,7 @@ internal fun Pager(
ConsumeFlingNestedScrollConnection(
consumeHorizontal = !isVertical,
consumeVertical = isVertical,
pagerState = state,
)
}

Expand Down Expand Up @@ -430,9 +431,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,
Expand All @@ -446,9 +449,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)
}
}
}

Expand Down
Expand Up @@ -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 {
Expand Down
Expand Up @@ -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 {
Expand Down

0 comments on commit 9706080

Please sign in to comment.