Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +12 −3 Original line number Original line Diff line number Diff line Loading @@ -521,6 +521,7 @@ private fun SwipeTransition( } } return SwipeTransition( return SwipeTransition( layoutImpl = layoutImpl, layoutState = layoutState, layoutState = layoutState, coroutineScope = coroutineScope, coroutineScope = coroutineScope, key = result.transitionKey, key = result.transitionKey, Loading @@ -534,6 +535,7 @@ private fun SwipeTransition( private fun SwipeTransition(old: SwipeTransition): SwipeTransition { private fun SwipeTransition(old: SwipeTransition): SwipeTransition { return SwipeTransition( return SwipeTransition( layoutImpl = old.layoutImpl, layoutState = old.layoutState, layoutState = old.layoutState, coroutineScope = old.coroutineScope, coroutineScope = old.coroutineScope, key = old.key, key = old.key, Loading @@ -550,6 +552,7 @@ private fun SwipeTransition(old: SwipeTransition): SwipeTransition { } } private class SwipeTransition( private class SwipeTransition( val layoutImpl: SceneTransitionLayoutImpl, val layoutState: BaseSceneTransitionLayoutState, val layoutState: BaseSceneTransitionLayoutState, val coroutineScope: CoroutineScope, val coroutineScope: CoroutineScope, val key: TransitionKey?, val key: TransitionKey?, Loading Loading @@ -607,6 +610,12 @@ private class SwipeTransition( override val overscrollScope: OverscrollScope = override val overscrollScope: OverscrollScope = object : OverscrollScope { object : OverscrollScope { override val density: Float get() = layoutImpl.density.density override val fontScale: Float get() = layoutImpl.density.fontScale override val absoluteDistance: Float override val absoluteDistance: Float get() = distance().absoluteValue get() = distance().absoluteValue } } Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt +2 −1 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.SpringSpec import androidx.compose.animation.core.SpringSpec import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified import com.android.compose.animation.scene.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified Loading Loading @@ -192,7 +193,7 @@ interface OverscrollBuilder : BaseTransitionBuilder { ) ) } } interface OverscrollScope { interface OverscrollScope : Density { /** /** * Return the absolute distance between fromScene and toScene, if available, otherwise * Return the absolute distance between fromScene and toScene, if available, otherwise * [DistanceUnspecified]. * [DistanceUnspecified]. Loading packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt +40 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.assertPositionInRootIsEqualTo import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.test.performTouchInput Loading Loading @@ -594,4 +595,43 @@ class SwipeToSceneTest { assertThat(transition).hasToScene(SceneB) assertThat(transition).hasToScene(SceneB) assertThat(transition).hasProgress(0.5f, tolerance = 0.01f) assertThat(transition).hasProgress(0.5f, tolerance = 0.01f) } } @Test fun overscrollScopeExtendsDensity() { val swipeDistance = 100.dp val state = rule.runOnUiThread { MutableSceneTransitionLayoutState( SceneA, transitions { from(SceneA, to = SceneB) { distance = FixedDistance(swipeDistance) } overscroll(SceneB, Orientation.Vertical) { translate(TestElements.Foo, x = { 20.dp.toPx() }, y = { 30.dp.toPx() }) } } ) } val layoutSize = 200.dp var touchSlop = 0f rule.setContent { touchSlop = LocalViewConfiguration.current.touchSlop SceneTransitionLayout(state, Modifier.size(layoutSize)) { scene(SceneA, userActions = mapOf(Swipe.Down to SceneB)) { Box(Modifier.fillMaxSize()) } scene(SceneB) { Box(Modifier.element(TestElements.Foo).fillMaxSize()) } } } // Swipe down by twice the swipe distance so that we are at 100% overscrolling on scene B. rule.onRoot().performTouchInput { val middle = (layoutSize / 2).toPx() down(Offset(middle, middle)) moveBy(Offset(0f, touchSlop + (swipeDistance * 2).toPx()), delayMillis = 1_000) } // Foo should be translated by (20dp, 30dp). rule.onNode(isElement(TestElements.Foo)).assertPositionInRootIsEqualTo(20.dp, 30.dp) } } } packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -41,8 +41,10 @@ fun transition( return object : TransitionState.Transition(from, to), TransitionState.HasOverscrollProperties { return object : TransitionState.Transition(from, to), TransitionState.HasOverscrollProperties { override val currentScene: SceneKey override val currentScene: SceneKey get() = current() get() = current() override val progress: Float override val progress: Float get() = progress() get() = progress() override val progressVelocity: Float override val progressVelocity: Float get() = progressVelocity() get() = progressVelocity() Loading @@ -53,6 +55,8 @@ fun transition( override val orientation: Orientation = orientation override val orientation: Orientation = orientation override val overscrollScope: OverscrollScope = override val overscrollScope: OverscrollScope = object : OverscrollScope { object : OverscrollScope { override val density: Float = 1f override val fontScale: Float = 1f override val absoluteDistance = 0f override val absoluteDistance = 0f } } Loading Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +12 −3 Original line number Original line Diff line number Diff line Loading @@ -521,6 +521,7 @@ private fun SwipeTransition( } } return SwipeTransition( return SwipeTransition( layoutImpl = layoutImpl, layoutState = layoutState, layoutState = layoutState, coroutineScope = coroutineScope, coroutineScope = coroutineScope, key = result.transitionKey, key = result.transitionKey, Loading @@ -534,6 +535,7 @@ private fun SwipeTransition( private fun SwipeTransition(old: SwipeTransition): SwipeTransition { private fun SwipeTransition(old: SwipeTransition): SwipeTransition { return SwipeTransition( return SwipeTransition( layoutImpl = old.layoutImpl, layoutState = old.layoutState, layoutState = old.layoutState, coroutineScope = old.coroutineScope, coroutineScope = old.coroutineScope, key = old.key, key = old.key, Loading @@ -550,6 +552,7 @@ private fun SwipeTransition(old: SwipeTransition): SwipeTransition { } } private class SwipeTransition( private class SwipeTransition( val layoutImpl: SceneTransitionLayoutImpl, val layoutState: BaseSceneTransitionLayoutState, val layoutState: BaseSceneTransitionLayoutState, val coroutineScope: CoroutineScope, val coroutineScope: CoroutineScope, val key: TransitionKey?, val key: TransitionKey?, Loading Loading @@ -607,6 +610,12 @@ private class SwipeTransition( override val overscrollScope: OverscrollScope = override val overscrollScope: OverscrollScope = object : OverscrollScope { object : OverscrollScope { override val density: Float get() = layoutImpl.density.density override val fontScale: Float get() = layoutImpl.density.fontScale override val absoluteDistance: Float override val absoluteDistance: Float get() = distance().absoluteValue get() = distance().absoluteValue } } Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt +2 −1 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.SpringSpec import androidx.compose.animation.core.SpringSpec import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified import com.android.compose.animation.scene.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified Loading Loading @@ -192,7 +193,7 @@ interface OverscrollBuilder : BaseTransitionBuilder { ) ) } } interface OverscrollScope { interface OverscrollScope : Density { /** /** * Return the absolute distance between fromScene and toScene, if available, otherwise * Return the absolute distance between fromScene and toScene, if available, otherwise * [DistanceUnspecified]. * [DistanceUnspecified]. Loading
packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt +40 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.assertPositionInRootIsEqualTo import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.test.performTouchInput Loading Loading @@ -594,4 +595,43 @@ class SwipeToSceneTest { assertThat(transition).hasToScene(SceneB) assertThat(transition).hasToScene(SceneB) assertThat(transition).hasProgress(0.5f, tolerance = 0.01f) assertThat(transition).hasProgress(0.5f, tolerance = 0.01f) } } @Test fun overscrollScopeExtendsDensity() { val swipeDistance = 100.dp val state = rule.runOnUiThread { MutableSceneTransitionLayoutState( SceneA, transitions { from(SceneA, to = SceneB) { distance = FixedDistance(swipeDistance) } overscroll(SceneB, Orientation.Vertical) { translate(TestElements.Foo, x = { 20.dp.toPx() }, y = { 30.dp.toPx() }) } } ) } val layoutSize = 200.dp var touchSlop = 0f rule.setContent { touchSlop = LocalViewConfiguration.current.touchSlop SceneTransitionLayout(state, Modifier.size(layoutSize)) { scene(SceneA, userActions = mapOf(Swipe.Down to SceneB)) { Box(Modifier.fillMaxSize()) } scene(SceneB) { Box(Modifier.element(TestElements.Foo).fillMaxSize()) } } } // Swipe down by twice the swipe distance so that we are at 100% overscrolling on scene B. rule.onRoot().performTouchInput { val middle = (layoutSize / 2).toPx() down(Offset(middle, middle)) moveBy(Offset(0f, touchSlop + (swipeDistance * 2).toPx()), delayMillis = 1_000) } // Foo should be translated by (20dp, 30dp). rule.onNode(isElement(TestElements.Foo)).assertPositionInRootIsEqualTo(20.dp, 30.dp) } } }
packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -41,8 +41,10 @@ fun transition( return object : TransitionState.Transition(from, to), TransitionState.HasOverscrollProperties { return object : TransitionState.Transition(from, to), TransitionState.HasOverscrollProperties { override val currentScene: SceneKey override val currentScene: SceneKey get() = current() get() = current() override val progress: Float override val progress: Float get() = progress() get() = progress() override val progressVelocity: Float override val progressVelocity: Float get() = progressVelocity() get() = progressVelocity() Loading @@ -53,6 +55,8 @@ fun transition( override val orientation: Orientation = orientation override val orientation: Orientation = orientation override val overscrollScope: OverscrollScope = override val overscrollScope: OverscrollScope = object : OverscrollScope { object : OverscrollScope { override val density: Float = 1f override val fontScale: Float = 1f override val absoluteDistance = 0f override val absoluteDistance = 0f } } Loading