Loading packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt +38 −67 Original line number Diff line number Diff line Loading @@ -34,71 +34,76 @@ internal typealias SuspendedValue<T> = suspend () -> T * Note: Call [reset] before destroying this object to make sure you always get a call to [onStop] * after [onStart]. * * @sample com.android.compose.animation.scene.rememberSwipeToSceneNestedScrollConnection * @sample LargeTopAppBarNestedScrollConnection * @sample com.android.compose.animation.scene.NestedScrollHandlerImpl.nestedScrollConnection */ class PriorityNestedScrollConnection( private val canStartPreScroll: (offsetAvailable: Offset, offsetBeforeStart: Offset) -> Boolean, private val canStartPostScroll: (offsetAvailable: Offset, offsetBeforeStart: Offset) -> Boolean, private val canStartPostFling: (velocityAvailable: Velocity) -> Boolean, orientation: Orientation, private val canStartPreScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, private val canStartPostScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, private val canStartPostFling: (velocityAvailable: Float) -> Boolean, private val canContinueScroll: (source: NestedScrollSource) -> Boolean, private val canScrollOnFling: Boolean, private val onStart: (offsetAvailable: Offset) -> Unit, private val onScroll: (offsetAvailable: Offset) -> Offset, private val onStop: (velocityAvailable: Velocity) -> SuspendedValue<Velocity>, ) : NestedScrollConnection { private val onStart: (offsetAvailable: Float) -> Unit, private val onScroll: (offsetAvailable: Float) -> Float, private val onStop: (velocityAvailable: Float) -> SuspendedValue<Float>, ) : NestedScrollConnection, SpaceVectorConverter by SpaceVectorConverter(orientation) { /** In priority mode [onPreScroll] events are first consumed by the parent, via [onScroll]. */ private var isPriorityMode = false private var offsetScrolledBeforePriorityMode = Offset.Zero private var offsetScrolledBeforePriorityMode = 0f override fun onPostScroll( consumed: Offset, available: Offset, source: NestedScrollSource, ): Offset { val availableFloat = available.toFloat() // The offset before the start takes into account the up and down movements, starting from // the beginning or from the last fling gesture. val offsetBeforeStart = offsetScrolledBeforePriorityMode - available val offsetBeforeStart = offsetScrolledBeforePriorityMode - availableFloat if ( isPriorityMode || (source == NestedScrollSource.SideEffect && !canScrollOnFling) || !canStartPostScroll(available, offsetBeforeStart) !canStartPostScroll(availableFloat, offsetBeforeStart) ) { // The priority mode cannot start so we won't consume the available offset. return Offset.Zero } return onPriorityStart(available) return onPriorityStart(availableFloat).toOffset() } override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { if (!isPriorityMode) { if (source == NestedScrollSource.UserInput || canScrollOnFling) { if (canStartPreScroll(available, offsetScrolledBeforePriorityMode)) { return onPriorityStart(available) val availableFloat = available.toFloat() if (canStartPreScroll(availableFloat, offsetScrolledBeforePriorityMode)) { return onPriorityStart(availableFloat).toOffset() } // We want to track the amount of offset consumed before entering priority mode offsetScrolledBeforePriorityMode += available offsetScrolledBeforePriorityMode += availableFloat } return Offset.Zero } val availableFloat = available.toFloat() if (!canContinueScroll(source)) { // Step 3a: We have lost priority and we no longer need to intercept scroll events. onPriorityStop(velocity = Velocity.Zero) onPriorityStop(velocity = 0f) // We've just reset offsetScrolledBeforePriorityMode to Offset.Zero // We've just reset offsetScrolledBeforePriorityMode to 0f // We want to track the amount of offset consumed before entering priority mode offsetScrolledBeforePriorityMode += available offsetScrolledBeforePriorityMode += availableFloat return Offset.Zero } // Step 2: We have the priority and can consume the scroll events. return onScroll(available) return onScroll(availableFloat).toOffset() } override suspend fun onPreFling(available: Velocity): Velocity { Loading @@ -108,15 +113,16 @@ class PriorityNestedScrollConnection( } // Step 3b: The finger is lifted, we can stop intercepting scroll events and use the speed // of the fling gesture. return onPriorityStop(velocity = available).invoke() return onPriorityStop(velocity = available.toFloat()).invoke().toVelocity() } override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { val availableFloat = available.toFloat() if (isPriorityMode) { return onPriorityStop(velocity = available).invoke() return onPriorityStop(velocity = availableFloat).invoke().toVelocity() } if (!canStartPostFling(available)) { if (!canStartPostFling(availableFloat)) { return Velocity.Zero } Loading @@ -124,11 +130,11 @@ class PriorityNestedScrollConnection( // given the available velocity. // TODO(b/291053278): Remove canStartPostFling() and instead make it possible to define the // overscroll behavior on the Scene level. val smallOffset = Offset(available.x.sign, available.y.sign) onPriorityStart(available = smallOffset) val smallOffset = availableFloat.sign onPriorityStart(availableOffset = smallOffset) // This is the last event of a scroll gesture. return onPriorityStop(available).invoke() return onPriorityStop(availableFloat).invoke().toVelocity() } /** Loading @@ -138,10 +144,10 @@ class PriorityNestedScrollConnection( */ fun reset() { // Step 3c: To ensure that an onStop is always called for every onStart. onPriorityStop(velocity = Velocity.Zero) onPriorityStop(velocity = 0f) } private fun onPriorityStart(available: Offset): Offset { private fun onPriorityStart(availableOffset: Float): Float { if (isPriorityMode) { error("This should never happen, onPriorityStart() was called when isPriorityMode") } Loading @@ -152,17 +158,17 @@ class PriorityNestedScrollConnection( // Note: onStop will be called if we cannot continue to scroll (step 3a), or the finger is // lifted (step 3b), or this object has been destroyed (step 3c). onStart(available) onStart(availableOffset) return onScroll(available) return onScroll(availableOffset) } private fun onPriorityStop(velocity: Velocity): SuspendedValue<Velocity> { private fun onPriorityStop(velocity: Float): SuspendedValue<Float> { // We can restart tracking the consumed offsets from scratch. offsetScrolledBeforePriorityMode = Offset.Zero offsetScrolledBeforePriorityMode = 0f if (!isPriorityMode) { return { Velocity.Zero } return { 0f } } isPriorityMode = false Loading @@ -170,38 +176,3 @@ class PriorityNestedScrollConnection( return onStop(velocity) } } fun PriorityNestedScrollConnection( orientation: Orientation, canStartPreScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, canStartPostScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, canStartPostFling: (velocityAvailable: Float) -> Boolean, canContinueScroll: (source: NestedScrollSource) -> Boolean, canScrollOnFling: Boolean, onStart: (offsetAvailable: Float) -> Unit, onScroll: (offsetAvailable: Float) -> Float, onStop: (velocityAvailable: Float) -> SuspendedValue<Float>, ) = with(SpaceVectorConverter(orientation)) { PriorityNestedScrollConnection( canStartPreScroll = { offsetAvailable: Offset, offsetBeforeStart: Offset -> canStartPreScroll(offsetAvailable.toFloat(), offsetBeforeStart.toFloat()) }, canStartPostScroll = { offsetAvailable: Offset, offsetBeforeStart: Offset -> canStartPostScroll(offsetAvailable.toFloat(), offsetBeforeStart.toFloat()) }, canStartPostFling = { velocityAvailable: Velocity -> canStartPostFling(velocityAvailable.toFloat()) }, canContinueScroll = canContinueScroll, canScrollOnFling = canScrollOnFling, onStart = { offsetAvailable -> onStart(offsetAvailable.toFloat()) }, onScroll = { offsetAvailable: Offset -> onScroll(offsetAvailable.toFloat()).toOffset() }, onStop = { velocityAvailable: Velocity -> val consumedVelocity = onStop(velocityAvailable.toFloat()) suspend { consumedVelocity.invoke().toVelocity() } }, ) } packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt +26 −29 Original line number Diff line number Diff line Loading @@ -18,8 +18,9 @@ package com.android.compose.nestedscroll import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.UserInput import androidx.compose.ui.unit.Velocity import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat Loading @@ -35,13 +36,14 @@ class PriorityNestedScrollConnectionTest { private var canStartPostFling = false private var canContinueScroll = false private var isStarted = false private var lastScroll: Offset? = null private var returnOnScroll = Offset.Zero private var lastStop: Velocity? = null private var returnOnStop = Velocity.Zero private var lastScroll: Float? = null private var returnOnScroll = 0f private var lastStop: Float? = null private var returnOnStop = 0f private val scrollConnection = PriorityNestedScrollConnection( orientation = Orientation.Vertical, canStartPreScroll = { _, _ -> canStartPreScroll }, canStartPostScroll = { _, _ -> canStartPostScroll }, canStartPostFling = { canStartPostFling }, Loading @@ -58,11 +60,6 @@ class PriorityNestedScrollConnectionTest { }, ) private val offset1 = Offset(1f, 1f) private val offset2 = Offset(2f, 2f) private val velocity1 = Velocity(1f, 1f) private val velocity2 = Velocity(2f, 2f) @Test fun step1_priorityModeShouldStartOnlyOnPreScroll() = runTest { canStartPreScroll = true Loading @@ -70,7 +67,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) assertThat(isStarted).isEqualTo(false) Loading @@ -80,7 +77,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostFling(consumed = Velocity.Zero, available = Velocity.Zero) assertThat(isStarted).isEqualTo(false) scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(isStarted).isEqualTo(true) } Loading @@ -89,7 +86,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) } Loading @@ -97,7 +94,7 @@ class PriorityNestedScrollConnectionTest { fun step1_priorityModeShouldStartOnlyOnPostScroll() = runTest { canStartPostScroll = true scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(isStarted).isEqualTo(false) scrollConnection.onPreFling(available = Velocity.Zero) Loading @@ -115,7 +112,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) assertThat(isStarted).isEqualTo(false) Loading @@ -128,12 +125,12 @@ class PriorityNestedScrollConnectionTest { canStartPostScroll = true scrollConnection.onPostScroll( consumed = offset1, available = offset2, source = NestedScrollSource.Drag, consumed = Offset(1f, 1f), available = Offset(2f, 2f), source = UserInput, ) assertThat(lastScroll).isEqualTo(offset2) assertThat(lastScroll).isEqualTo(2f) } @Test Loading @@ -141,13 +138,13 @@ class PriorityNestedScrollConnectionTest { startPriorityModePostScroll() canContinueScroll = true scrollConnection.onPreScroll(available = offset1, source = NestedScrollSource.Drag) assertThat(lastScroll).isEqualTo(offset1) scrollConnection.onPreScroll(available = Offset(1f, 1f), source = UserInput) assertThat(lastScroll).isEqualTo(1f) canContinueScroll = false scrollConnection.onPreScroll(available = offset2, source = NestedScrollSource.Drag) assertThat(lastScroll).isNotEqualTo(offset2) assertThat(lastScroll).isEqualTo(offset1) scrollConnection.onPreScroll(available = Offset(2f, 2f), source = UserInput) assertThat(lastScroll).isNotEqualTo(2f) assertThat(lastScroll).isEqualTo(1f) } @Test Loading @@ -155,7 +152,7 @@ class PriorityNestedScrollConnectionTest { startPriorityModePostScroll() canContinueScroll = false scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(lastStop).isNotNull() } Loading Loading @@ -184,22 +181,22 @@ class PriorityNestedScrollConnectionTest { fun receive_onPostFling() = runTest { canStartPostFling = true scrollConnection.onPostFling(consumed = velocity1, available = velocity2) scrollConnection.onPostFling(consumed = Velocity(1f, 1f), available = Velocity(2f, 2f)) assertThat(lastStop).isEqualTo(velocity2) assertThat(lastStop).isEqualTo(2f) } @Test fun step1_priorityModeShouldStartOnlyOnPostFling() = runTest { canStartPostFling = true scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(isStarted).isEqualTo(false) scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) assertThat(isStarted).isEqualTo(false) Loading Loading
packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt +38 −67 Original line number Diff line number Diff line Loading @@ -34,71 +34,76 @@ internal typealias SuspendedValue<T> = suspend () -> T * Note: Call [reset] before destroying this object to make sure you always get a call to [onStop] * after [onStart]. * * @sample com.android.compose.animation.scene.rememberSwipeToSceneNestedScrollConnection * @sample LargeTopAppBarNestedScrollConnection * @sample com.android.compose.animation.scene.NestedScrollHandlerImpl.nestedScrollConnection */ class PriorityNestedScrollConnection( private val canStartPreScroll: (offsetAvailable: Offset, offsetBeforeStart: Offset) -> Boolean, private val canStartPostScroll: (offsetAvailable: Offset, offsetBeforeStart: Offset) -> Boolean, private val canStartPostFling: (velocityAvailable: Velocity) -> Boolean, orientation: Orientation, private val canStartPreScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, private val canStartPostScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, private val canStartPostFling: (velocityAvailable: Float) -> Boolean, private val canContinueScroll: (source: NestedScrollSource) -> Boolean, private val canScrollOnFling: Boolean, private val onStart: (offsetAvailable: Offset) -> Unit, private val onScroll: (offsetAvailable: Offset) -> Offset, private val onStop: (velocityAvailable: Velocity) -> SuspendedValue<Velocity>, ) : NestedScrollConnection { private val onStart: (offsetAvailable: Float) -> Unit, private val onScroll: (offsetAvailable: Float) -> Float, private val onStop: (velocityAvailable: Float) -> SuspendedValue<Float>, ) : NestedScrollConnection, SpaceVectorConverter by SpaceVectorConverter(orientation) { /** In priority mode [onPreScroll] events are first consumed by the parent, via [onScroll]. */ private var isPriorityMode = false private var offsetScrolledBeforePriorityMode = Offset.Zero private var offsetScrolledBeforePriorityMode = 0f override fun onPostScroll( consumed: Offset, available: Offset, source: NestedScrollSource, ): Offset { val availableFloat = available.toFloat() // The offset before the start takes into account the up and down movements, starting from // the beginning or from the last fling gesture. val offsetBeforeStart = offsetScrolledBeforePriorityMode - available val offsetBeforeStart = offsetScrolledBeforePriorityMode - availableFloat if ( isPriorityMode || (source == NestedScrollSource.SideEffect && !canScrollOnFling) || !canStartPostScroll(available, offsetBeforeStart) !canStartPostScroll(availableFloat, offsetBeforeStart) ) { // The priority mode cannot start so we won't consume the available offset. return Offset.Zero } return onPriorityStart(available) return onPriorityStart(availableFloat).toOffset() } override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { if (!isPriorityMode) { if (source == NestedScrollSource.UserInput || canScrollOnFling) { if (canStartPreScroll(available, offsetScrolledBeforePriorityMode)) { return onPriorityStart(available) val availableFloat = available.toFloat() if (canStartPreScroll(availableFloat, offsetScrolledBeforePriorityMode)) { return onPriorityStart(availableFloat).toOffset() } // We want to track the amount of offset consumed before entering priority mode offsetScrolledBeforePriorityMode += available offsetScrolledBeforePriorityMode += availableFloat } return Offset.Zero } val availableFloat = available.toFloat() if (!canContinueScroll(source)) { // Step 3a: We have lost priority and we no longer need to intercept scroll events. onPriorityStop(velocity = Velocity.Zero) onPriorityStop(velocity = 0f) // We've just reset offsetScrolledBeforePriorityMode to Offset.Zero // We've just reset offsetScrolledBeforePriorityMode to 0f // We want to track the amount of offset consumed before entering priority mode offsetScrolledBeforePriorityMode += available offsetScrolledBeforePriorityMode += availableFloat return Offset.Zero } // Step 2: We have the priority and can consume the scroll events. return onScroll(available) return onScroll(availableFloat).toOffset() } override suspend fun onPreFling(available: Velocity): Velocity { Loading @@ -108,15 +113,16 @@ class PriorityNestedScrollConnection( } // Step 3b: The finger is lifted, we can stop intercepting scroll events and use the speed // of the fling gesture. return onPriorityStop(velocity = available).invoke() return onPriorityStop(velocity = available.toFloat()).invoke().toVelocity() } override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { val availableFloat = available.toFloat() if (isPriorityMode) { return onPriorityStop(velocity = available).invoke() return onPriorityStop(velocity = availableFloat).invoke().toVelocity() } if (!canStartPostFling(available)) { if (!canStartPostFling(availableFloat)) { return Velocity.Zero } Loading @@ -124,11 +130,11 @@ class PriorityNestedScrollConnection( // given the available velocity. // TODO(b/291053278): Remove canStartPostFling() and instead make it possible to define the // overscroll behavior on the Scene level. val smallOffset = Offset(available.x.sign, available.y.sign) onPriorityStart(available = smallOffset) val smallOffset = availableFloat.sign onPriorityStart(availableOffset = smallOffset) // This is the last event of a scroll gesture. return onPriorityStop(available).invoke() return onPriorityStop(availableFloat).invoke().toVelocity() } /** Loading @@ -138,10 +144,10 @@ class PriorityNestedScrollConnection( */ fun reset() { // Step 3c: To ensure that an onStop is always called for every onStart. onPriorityStop(velocity = Velocity.Zero) onPriorityStop(velocity = 0f) } private fun onPriorityStart(available: Offset): Offset { private fun onPriorityStart(availableOffset: Float): Float { if (isPriorityMode) { error("This should never happen, onPriorityStart() was called when isPriorityMode") } Loading @@ -152,17 +158,17 @@ class PriorityNestedScrollConnection( // Note: onStop will be called if we cannot continue to scroll (step 3a), or the finger is // lifted (step 3b), or this object has been destroyed (step 3c). onStart(available) onStart(availableOffset) return onScroll(available) return onScroll(availableOffset) } private fun onPriorityStop(velocity: Velocity): SuspendedValue<Velocity> { private fun onPriorityStop(velocity: Float): SuspendedValue<Float> { // We can restart tracking the consumed offsets from scratch. offsetScrolledBeforePriorityMode = Offset.Zero offsetScrolledBeforePriorityMode = 0f if (!isPriorityMode) { return { Velocity.Zero } return { 0f } } isPriorityMode = false Loading @@ -170,38 +176,3 @@ class PriorityNestedScrollConnection( return onStop(velocity) } } fun PriorityNestedScrollConnection( orientation: Orientation, canStartPreScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, canStartPostScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, canStartPostFling: (velocityAvailable: Float) -> Boolean, canContinueScroll: (source: NestedScrollSource) -> Boolean, canScrollOnFling: Boolean, onStart: (offsetAvailable: Float) -> Unit, onScroll: (offsetAvailable: Float) -> Float, onStop: (velocityAvailable: Float) -> SuspendedValue<Float>, ) = with(SpaceVectorConverter(orientation)) { PriorityNestedScrollConnection( canStartPreScroll = { offsetAvailable: Offset, offsetBeforeStart: Offset -> canStartPreScroll(offsetAvailable.toFloat(), offsetBeforeStart.toFloat()) }, canStartPostScroll = { offsetAvailable: Offset, offsetBeforeStart: Offset -> canStartPostScroll(offsetAvailable.toFloat(), offsetBeforeStart.toFloat()) }, canStartPostFling = { velocityAvailable: Velocity -> canStartPostFling(velocityAvailable.toFloat()) }, canContinueScroll = canContinueScroll, canScrollOnFling = canScrollOnFling, onStart = { offsetAvailable -> onStart(offsetAvailable.toFloat()) }, onScroll = { offsetAvailable: Offset -> onScroll(offsetAvailable.toFloat()).toOffset() }, onStop = { velocityAvailable: Velocity -> val consumedVelocity = onStop(velocityAvailable.toFloat()) suspend { consumedVelocity.invoke().toVelocity() } }, ) }
packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt +26 −29 Original line number Diff line number Diff line Loading @@ -18,8 +18,9 @@ package com.android.compose.nestedscroll import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.UserInput import androidx.compose.ui.unit.Velocity import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat Loading @@ -35,13 +36,14 @@ class PriorityNestedScrollConnectionTest { private var canStartPostFling = false private var canContinueScroll = false private var isStarted = false private var lastScroll: Offset? = null private var returnOnScroll = Offset.Zero private var lastStop: Velocity? = null private var returnOnStop = Velocity.Zero private var lastScroll: Float? = null private var returnOnScroll = 0f private var lastStop: Float? = null private var returnOnStop = 0f private val scrollConnection = PriorityNestedScrollConnection( orientation = Orientation.Vertical, canStartPreScroll = { _, _ -> canStartPreScroll }, canStartPostScroll = { _, _ -> canStartPostScroll }, canStartPostFling = { canStartPostFling }, Loading @@ -58,11 +60,6 @@ class PriorityNestedScrollConnectionTest { }, ) private val offset1 = Offset(1f, 1f) private val offset2 = Offset(2f, 2f) private val velocity1 = Velocity(1f, 1f) private val velocity2 = Velocity(2f, 2f) @Test fun step1_priorityModeShouldStartOnlyOnPreScroll() = runTest { canStartPreScroll = true Loading @@ -70,7 +67,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) assertThat(isStarted).isEqualTo(false) Loading @@ -80,7 +77,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostFling(consumed = Velocity.Zero, available = Velocity.Zero) assertThat(isStarted).isEqualTo(false) scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(isStarted).isEqualTo(true) } Loading @@ -89,7 +86,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) } Loading @@ -97,7 +94,7 @@ class PriorityNestedScrollConnectionTest { fun step1_priorityModeShouldStartOnlyOnPostScroll() = runTest { canStartPostScroll = true scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(isStarted).isEqualTo(false) scrollConnection.onPreFling(available = Velocity.Zero) Loading @@ -115,7 +112,7 @@ class PriorityNestedScrollConnectionTest { scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) assertThat(isStarted).isEqualTo(false) Loading @@ -128,12 +125,12 @@ class PriorityNestedScrollConnectionTest { canStartPostScroll = true scrollConnection.onPostScroll( consumed = offset1, available = offset2, source = NestedScrollSource.Drag, consumed = Offset(1f, 1f), available = Offset(2f, 2f), source = UserInput, ) assertThat(lastScroll).isEqualTo(offset2) assertThat(lastScroll).isEqualTo(2f) } @Test Loading @@ -141,13 +138,13 @@ class PriorityNestedScrollConnectionTest { startPriorityModePostScroll() canContinueScroll = true scrollConnection.onPreScroll(available = offset1, source = NestedScrollSource.Drag) assertThat(lastScroll).isEqualTo(offset1) scrollConnection.onPreScroll(available = Offset(1f, 1f), source = UserInput) assertThat(lastScroll).isEqualTo(1f) canContinueScroll = false scrollConnection.onPreScroll(available = offset2, source = NestedScrollSource.Drag) assertThat(lastScroll).isNotEqualTo(offset2) assertThat(lastScroll).isEqualTo(offset1) scrollConnection.onPreScroll(available = Offset(2f, 2f), source = UserInput) assertThat(lastScroll).isNotEqualTo(2f) assertThat(lastScroll).isEqualTo(1f) } @Test Loading @@ -155,7 +152,7 @@ class PriorityNestedScrollConnectionTest { startPriorityModePostScroll() canContinueScroll = false scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(lastStop).isNotNull() } Loading Loading @@ -184,22 +181,22 @@ class PriorityNestedScrollConnectionTest { fun receive_onPostFling() = runTest { canStartPostFling = true scrollConnection.onPostFling(consumed = velocity1, available = velocity2) scrollConnection.onPostFling(consumed = Velocity(1f, 1f), available = Velocity(2f, 2f)) assertThat(lastStop).isEqualTo(velocity2) assertThat(lastStop).isEqualTo(2f) } @Test fun step1_priorityModeShouldStartOnlyOnPostFling() = runTest { canStartPostFling = true scrollConnection.onPreScroll(available = Offset.Zero, source = NestedScrollSource.Drag) scrollConnection.onPreScroll(available = Offset.Zero, source = UserInput) assertThat(isStarted).isEqualTo(false) scrollConnection.onPostScroll( consumed = Offset.Zero, available = Offset.Zero, source = NestedScrollSource.Drag, source = UserInput, ) assertThat(isStarted).isEqualTo(false) Loading