diff options
2 files changed, 29 insertions, 0 deletions
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt index 5fda77a3e0ae..f8ba7296782b 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt @@ -117,6 +117,9 @@ sealed interface MutableSceneTransitionLayoutState : SceneTransitionLayoutState coroutineScope: CoroutineScope, transitionKey: TransitionKey? = null, ): TransitionState.Transition? + + /** Immediately snap to the given [scene]. */ + fun snapToScene(scene: SceneKey) } /** @@ -735,6 +738,17 @@ internal class MutableSceneTransitionLayoutStateImpl( override fun CoroutineScope.onChangeScene(scene: SceneKey) { setTargetScene(scene, coroutineScope = this) } + + override fun snapToScene(scene: SceneKey) { + // Force finish all transitions. + while (currentTransitions.isNotEmpty()) { + val transition = transitionStates[0] as TransitionState.Transition + finishTransition(transition, transition.currentScene) + } + + check(transitionStates.size == 1) + transitionStates[0] = TransitionState.Idle(scene) + } } private const val TAG = "SceneTransitionLayoutState" diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt index 93e94f8f95a2..4cd4400766a5 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt @@ -629,4 +629,19 @@ class SceneTransitionLayoutStateTest { Log.setWtfHandler(originalHandler) } } + + @Test + fun snapToScene() = runMonotonicClockTest { + val state = MutableSceneTransitionLayoutState(SceneA) + + // Transition to B. + state.setTargetScene(SceneB, coroutineScope = this) + val transition = assertThat(state.transitionState).isTransition() + assertThat(transition).hasCurrentScene(SceneB) + + // Snap to C. + state.snapToScene(SceneC) + assertThat(state.transitionState).isIdle() + assertThat(state.transitionState).hasCurrentScene(SceneC) + } } |