Loading packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/ContentOverscrollEffect.kt +10 −5 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ open class BaseContentOverscrollEffect( val currentOffset = animatable.value val sameDirection = deltaForAxis.sign == currentOffset.sign val consumedByPreScroll = if (abs(currentOffset) > 0.5 && !sameDirection) { if (abs(currentOffset) > 0f && !sameDirection) { // The user has scrolled in the opposite direction. val prevOverscrollValue = currentOffset val newOverscrollValue = currentOffset + deltaForAxis Loading Loading @@ -112,11 +112,16 @@ open class BaseContentOverscrollEffect( // If the user is dragging (not flinging), and there's any remaining scroll delta after the // standard scrolling logic has been applied, we add it to the overscroll. if (abs(overscrollDelta.toFloat()) > 0.5 && source == NestedScrollSource.UserInput) { animationScope.launch { animatable.snapTo(currentOffset + overscrollDelta.toFloat()) } val overscroll = overscrollDelta.toFloat() val consumedByPostScroll = if (abs(overscroll) > 0f && source == NestedScrollSource.UserInput) { animationScope.launch { animatable.snapTo(currentOffset + overscroll) } overscroll.toOffset() } else { Offset.Zero } return delta return consumedByPreScroll + consumedByScroll + consumedByPostScroll } override suspend fun applyToFling( Loading packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/effect/OffsetOverscrollEffectTest.kt +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.compose.gesture.effect import androidx.compose.animation.core.spring import androidx.compose.foundation.OverscrollEffect import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.ScrollableState Loading @@ -29,6 +30,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.testTag Loading Loading @@ -328,4 +330,20 @@ class OffsetOverscrollEffectTest { assertThat(info.scrollableState.isScrollInProgress).isFalse() assertThat(info.overscrollEffect.isInProgress).isFalse() } @Test fun applyToScroll_doesNotConsumeFlingScrolls() = runTest { val effect = OffsetOverscrollEffect(animationScope = this, animationSpec = spring()) assertThat( effect.applyToScroll(Offset(0f, 20f), source = NestedScrollSource.SideEffect) { scroll -> assertThat(scroll).isEqualTo(Offset(0f, 20f)) // Consume some of the delta during scroll. Offset(0f, 15f) } ) // The remaining offset was not consumed to overscroll given that the source is a fling. .isEqualTo(Offset(0f, 15f)) } } Loading
packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/ContentOverscrollEffect.kt +10 −5 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ open class BaseContentOverscrollEffect( val currentOffset = animatable.value val sameDirection = deltaForAxis.sign == currentOffset.sign val consumedByPreScroll = if (abs(currentOffset) > 0.5 && !sameDirection) { if (abs(currentOffset) > 0f && !sameDirection) { // The user has scrolled in the opposite direction. val prevOverscrollValue = currentOffset val newOverscrollValue = currentOffset + deltaForAxis Loading Loading @@ -112,11 +112,16 @@ open class BaseContentOverscrollEffect( // If the user is dragging (not flinging), and there's any remaining scroll delta after the // standard scrolling logic has been applied, we add it to the overscroll. if (abs(overscrollDelta.toFloat()) > 0.5 && source == NestedScrollSource.UserInput) { animationScope.launch { animatable.snapTo(currentOffset + overscrollDelta.toFloat()) } val overscroll = overscrollDelta.toFloat() val consumedByPostScroll = if (abs(overscroll) > 0f && source == NestedScrollSource.UserInput) { animationScope.launch { animatable.snapTo(currentOffset + overscroll) } overscroll.toOffset() } else { Offset.Zero } return delta return consumedByPreScroll + consumedByScroll + consumedByPostScroll } override suspend fun applyToFling( Loading
packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/effect/OffsetOverscrollEffectTest.kt +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.compose.gesture.effect import androidx.compose.animation.core.spring import androidx.compose.foundation.OverscrollEffect import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.ScrollableState Loading @@ -29,6 +30,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.testTag Loading Loading @@ -328,4 +330,20 @@ class OffsetOverscrollEffectTest { assertThat(info.scrollableState.isScrollInProgress).isFalse() assertThat(info.overscrollEffect.isInProgress).isFalse() } @Test fun applyToScroll_doesNotConsumeFlingScrolls() = runTest { val effect = OffsetOverscrollEffect(animationScope = this, animationSpec = spring()) assertThat( effect.applyToScroll(Offset(0f, 20f), source = NestedScrollSource.SideEffect) { scroll -> assertThat(scroll).isEqualTo(Offset(0f, 20f)) // Consume some of the delta during scroll. Offset(0f, 15f) } ) // The remaining offset was not consumed to overscroll given that the source is a fling. .isEqualTo(Offset(0f, 15f)) } }