Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt +4 −0 Original line number Diff line number Diff line Loading @@ -813,6 +813,10 @@ private fun shouldPlaceElement( element: Element, elementState: TransitionState, ): Boolean { if (element.key.placeAllCopies) { return true } val transition = when (elementState) { is TransitionState.Idle -> { Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt +10 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,16 @@ open class ElementKey( * or compose MovableElements. */ open val contentPicker: ElementContentPicker = DefaultElementContentPicker, /** * Whether we should place all copies of this element when it is shared. * * This should usually be false, but it can be useful when sharing a container that has a * different content in different scenes/overlays. That way the container will have the same * size and position in all scenes/overlays but all different contents will be placed and * visible on screen. */ val placeAllCopies: Boolean = false, ) : Key(debugName, identity), ElementMatcher { @VisibleForTesting // TODO(b/240432457): Make internal once PlatformComposeSceneTransitionLayoutTestsUtils can Loading packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt +61 −0 Original line number Diff line number Diff line Loading @@ -2519,4 +2519,65 @@ class ElementTest { .onNode(hasTestTag(contentTestTag) and hasParent(isElement(movable))) .assertSizeIsEqualTo(40.dp) } @Test fun placeAllCopies() { val foo = ElementKey("Foo", placeAllCopies = true) @Composable fun SceneScope.Foo(size: Dp, modifier: Modifier = Modifier) { Box(modifier.element(foo).size(size)) } rule.testTransition( fromSceneContent = { Box(Modifier.size(100.dp)) { Foo(size = 10.dp) } }, toSceneContent = { Box(Modifier.size(100.dp)) { Foo(size = 50.dp, Modifier.align(Alignment.BottomEnd)) } }, transition = { spec = tween(4 * 16, easing = LinearEasing) }, ) { before { onElement(foo, SceneA) .assertSizeIsEqualTo(10.dp) .assertPositionInRootIsEqualTo(0.dp, 0.dp) onElement(foo, SceneB).assertDoesNotExist() } at(16) { onElement(foo, SceneA) .assertSizeIsEqualTo(20.dp) .assertPositionInRootIsEqualTo(12.5.dp, 12.5.dp) onElement(foo, SceneB) .assertSizeIsEqualTo(20.dp) .assertPositionInRootIsEqualTo(12.5.dp, 12.5.dp) } at(32) { onElement(foo, SceneA) .assertSizeIsEqualTo(30.dp) .assertPositionInRootIsEqualTo(25.dp, 25.dp) onElement(foo, SceneB) .assertSizeIsEqualTo(30.dp) .assertPositionInRootIsEqualTo(25.dp, 25.dp) } at(48) { onElement(foo, SceneA) .assertSizeIsEqualTo(40.dp) .assertPositionInRootIsEqualTo(37.5.dp, 37.5.dp) onElement(foo, SceneB) .assertSizeIsEqualTo(40.dp) .assertPositionInRootIsEqualTo(37.5.dp, 37.5.dp) } after { onElement(foo, SceneA).assertDoesNotExist() onElement(foo, SceneB) .assertSizeIsEqualTo(50.dp) .assertPositionInRootIsEqualTo(50.dp, 50.dp) } } } } Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt +4 −0 Original line number Diff line number Diff line Loading @@ -813,6 +813,10 @@ private fun shouldPlaceElement( element: Element, elementState: TransitionState, ): Boolean { if (element.key.placeAllCopies) { return true } val transition = when (elementState) { is TransitionState.Idle -> { Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt +10 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,16 @@ open class ElementKey( * or compose MovableElements. */ open val contentPicker: ElementContentPicker = DefaultElementContentPicker, /** * Whether we should place all copies of this element when it is shared. * * This should usually be false, but it can be useful when sharing a container that has a * different content in different scenes/overlays. That way the container will have the same * size and position in all scenes/overlays but all different contents will be placed and * visible on screen. */ val placeAllCopies: Boolean = false, ) : Key(debugName, identity), ElementMatcher { @VisibleForTesting // TODO(b/240432457): Make internal once PlatformComposeSceneTransitionLayoutTestsUtils can Loading
packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt +61 −0 Original line number Diff line number Diff line Loading @@ -2519,4 +2519,65 @@ class ElementTest { .onNode(hasTestTag(contentTestTag) and hasParent(isElement(movable))) .assertSizeIsEqualTo(40.dp) } @Test fun placeAllCopies() { val foo = ElementKey("Foo", placeAllCopies = true) @Composable fun SceneScope.Foo(size: Dp, modifier: Modifier = Modifier) { Box(modifier.element(foo).size(size)) } rule.testTransition( fromSceneContent = { Box(Modifier.size(100.dp)) { Foo(size = 10.dp) } }, toSceneContent = { Box(Modifier.size(100.dp)) { Foo(size = 50.dp, Modifier.align(Alignment.BottomEnd)) } }, transition = { spec = tween(4 * 16, easing = LinearEasing) }, ) { before { onElement(foo, SceneA) .assertSizeIsEqualTo(10.dp) .assertPositionInRootIsEqualTo(0.dp, 0.dp) onElement(foo, SceneB).assertDoesNotExist() } at(16) { onElement(foo, SceneA) .assertSizeIsEqualTo(20.dp) .assertPositionInRootIsEqualTo(12.5.dp, 12.5.dp) onElement(foo, SceneB) .assertSizeIsEqualTo(20.dp) .assertPositionInRootIsEqualTo(12.5.dp, 12.5.dp) } at(32) { onElement(foo, SceneA) .assertSizeIsEqualTo(30.dp) .assertPositionInRootIsEqualTo(25.dp, 25.dp) onElement(foo, SceneB) .assertSizeIsEqualTo(30.dp) .assertPositionInRootIsEqualTo(25.dp, 25.dp) } at(48) { onElement(foo, SceneA) .assertSizeIsEqualTo(40.dp) .assertPositionInRootIsEqualTo(37.5.dp, 37.5.dp) onElement(foo, SceneB) .assertSizeIsEqualTo(40.dp) .assertPositionInRootIsEqualTo(37.5.dp, 37.5.dp) } after { onElement(foo, SceneA).assertDoesNotExist() onElement(foo, SceneB) .assertSizeIsEqualTo(50.dp) .assertPositionInRootIsEqualTo(50.dp, 50.dp) } } } }