Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt +17 −11 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ import com.android.compose.ui.util.lerp fun SceneScope.animateSharedIntAsState( value: Int, key: ValueKey, element: ElementKey, element: ElementKey?, canOverflow: Boolean = true, ): State<Int> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow) Loading Loading @@ -65,7 +65,7 @@ fun MovableElementScope.animateSharedIntAsState( fun SceneScope.animateSharedFloatAsState( value: Float, key: ValueKey, element: ElementKey, element: ElementKey?, canOverflow: Boolean = true, ): State<Float> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow) Loading Loading @@ -94,7 +94,7 @@ fun MovableElementScope.animateSharedFloatAsState( fun SceneScope.animateSharedDpAsState( value: Dp, key: ValueKey, element: ElementKey, element: ElementKey?, canOverflow: Boolean = true, ): State<Dp> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow) Loading Loading @@ -123,7 +123,7 @@ fun MovableElementScope.animateSharedDpAsState( fun SceneScope.animateSharedColorAsState( value: Color, key: ValueKey, element: ElementKey, element: ElementKey?, ): State<Color> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow = false) } Loading @@ -145,7 +145,7 @@ fun MovableElementScope.animateSharedColorAsState( internal fun <T> animateSharedValueAsState( layoutImpl: SceneTransitionLayoutImpl, scene: Scene, element: Element, element: Element?, key: ValueKey, value: T, lerp: (T, T, Float) -> T, Loading @@ -153,9 +153,9 @@ internal fun <T> animateSharedValueAsState( ): State<T> { val sharedValue = Snapshot.withoutReadObservation { element.sceneValues.getValue(scene.key).sharedValues.getOrPut(key) { Element.SharedValue(key, value) } as Element.SharedValue<T> val sharedValues = element?.sceneValues?.getValue(scene.key)?.sharedValues ?: scene.sharedValues sharedValues.getOrPut(key) { Element.SharedValue(key, value) } as Element.SharedValue<T> } if (value != sharedValue.value) { Loading @@ -169,7 +169,7 @@ internal fun <T> animateSharedValueAsState( private fun <T> computeValue( layoutImpl: SceneTransitionLayoutImpl, element: Element, element: Element?, sharedValue: Element.SharedValue<T>, lerp: (T, T, Float) -> T, canOverflow: Boolean, Loading @@ -184,8 +184,14 @@ private fun <T> computeValue( } fun sceneValue(scene: SceneKey): Element.SharedValue<T>? { val sceneValues = element.sceneValues[scene] ?: return null val value = sceneValues.sharedValues[sharedValue.key] ?: return null val sharedValues = if (element == null) { layoutImpl.scene(scene).sharedValues } else { element.sceneValues[scene]?.sharedValues } ?: return null val value = sharedValues[sharedValue.key] ?: return null return value as Element.SharedValue<T> } Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt +12 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.platform.testTag Loading @@ -44,6 +45,9 @@ internal class Scene( var zIndex by mutableFloatStateOf(zIndex) var size by mutableStateOf(IntSize.Zero) /** The shared values in this scene that are not tied to a specific element. */ val sharedValues = SnapshotStateMap<ValueKey, Element.SharedValue<*>>() @Composable fun Content(modifier: Modifier = Modifier) { Box(modifier.zIndex(zIndex).onPlaced { size = it.size }.testTag(key.testTag)) { Loading @@ -69,16 +73,18 @@ private class SceneScopeImpl( override fun <T> animateSharedValueAsState( value: T, key: ValueKey, element: ElementKey, element: ElementKey?, lerp: (T, T, Float) -> T, canOverflow: Boolean ): State<T> { val element = layoutImpl.elements[element] element?.let { key -> layoutImpl.elements[key] ?: error( "Element $element is not composed. Make sure to call animateSharedXAsState " + "Element $key is not composed. Make sure to call animateSharedXAsState " + "*after* Modifier.element(key)." ) } return animateSharedValueAsState( layoutImpl, Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt +4 −2 Original line number Diff line number Diff line Loading @@ -142,7 +142,9 @@ interface SceneScope { * * @param value the value of this shared value in the current scene. * @param key the key of this shared value. * @param element the element associated with this value. * @param element the element associated with this value. If `null`, this value will be * associated at the scene level, which means that [key] should be used maximum once in the * same scene. * @param lerp the *linear* interpolation function that should be used to interpolate between * two different values. Note that it has to be linear because the [fraction] passed to this * interpolator is already interpolated. Loading @@ -157,7 +159,7 @@ interface SceneScope { fun <T> animateSharedValueAsState( value: T, key: ValueKey, element: ElementKey, element: ElementKey?, lerp: (start: T, stop: T, fraction: Float) -> T, canOverflow: Boolean, ): State<T> Loading packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt +2 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ class AnimatedSharedAsStateTest { val int by animateSharedIntAsState(targetValues.int, TestValues.Value1, key) val float by animateSharedFloatAsState(targetValues.float, TestValues.Value2, key) val dp by animateSharedDpAsState(targetValues.dp, TestValues.Value3, key) val color by animateSharedColorAsState(targetValues.color, TestValues.Value4, key) val color by animateSharedColorAsState(targetValues.color, TestValues.Value4, element = null) // Make sure we read the values during composition, so that we recompose and call // onCurrentValueChanged() with the latest values. Loading Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt +17 −11 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ import com.android.compose.ui.util.lerp fun SceneScope.animateSharedIntAsState( value: Int, key: ValueKey, element: ElementKey, element: ElementKey?, canOverflow: Boolean = true, ): State<Int> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow) Loading Loading @@ -65,7 +65,7 @@ fun MovableElementScope.animateSharedIntAsState( fun SceneScope.animateSharedFloatAsState( value: Float, key: ValueKey, element: ElementKey, element: ElementKey?, canOverflow: Boolean = true, ): State<Float> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow) Loading Loading @@ -94,7 +94,7 @@ fun MovableElementScope.animateSharedFloatAsState( fun SceneScope.animateSharedDpAsState( value: Dp, key: ValueKey, element: ElementKey, element: ElementKey?, canOverflow: Boolean = true, ): State<Dp> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow) Loading Loading @@ -123,7 +123,7 @@ fun MovableElementScope.animateSharedDpAsState( fun SceneScope.animateSharedColorAsState( value: Color, key: ValueKey, element: ElementKey, element: ElementKey?, ): State<Color> { return animateSharedValueAsState(value, key, element, ::lerp, canOverflow = false) } Loading @@ -145,7 +145,7 @@ fun MovableElementScope.animateSharedColorAsState( internal fun <T> animateSharedValueAsState( layoutImpl: SceneTransitionLayoutImpl, scene: Scene, element: Element, element: Element?, key: ValueKey, value: T, lerp: (T, T, Float) -> T, Loading @@ -153,9 +153,9 @@ internal fun <T> animateSharedValueAsState( ): State<T> { val sharedValue = Snapshot.withoutReadObservation { element.sceneValues.getValue(scene.key).sharedValues.getOrPut(key) { Element.SharedValue(key, value) } as Element.SharedValue<T> val sharedValues = element?.sceneValues?.getValue(scene.key)?.sharedValues ?: scene.sharedValues sharedValues.getOrPut(key) { Element.SharedValue(key, value) } as Element.SharedValue<T> } if (value != sharedValue.value) { Loading @@ -169,7 +169,7 @@ internal fun <T> animateSharedValueAsState( private fun <T> computeValue( layoutImpl: SceneTransitionLayoutImpl, element: Element, element: Element?, sharedValue: Element.SharedValue<T>, lerp: (T, T, Float) -> T, canOverflow: Boolean, Loading @@ -184,8 +184,14 @@ private fun <T> computeValue( } fun sceneValue(scene: SceneKey): Element.SharedValue<T>? { val sceneValues = element.sceneValues[scene] ?: return null val value = sceneValues.sharedValues[sharedValue.key] ?: return null val sharedValues = if (element == null) { layoutImpl.scene(scene).sharedValues } else { element.sceneValues[scene]?.sharedValues } ?: return null val value = sharedValues[sharedValue.key] ?: return null return value as Element.SharedValue<T> } Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt +12 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.platform.testTag Loading @@ -44,6 +45,9 @@ internal class Scene( var zIndex by mutableFloatStateOf(zIndex) var size by mutableStateOf(IntSize.Zero) /** The shared values in this scene that are not tied to a specific element. */ val sharedValues = SnapshotStateMap<ValueKey, Element.SharedValue<*>>() @Composable fun Content(modifier: Modifier = Modifier) { Box(modifier.zIndex(zIndex).onPlaced { size = it.size }.testTag(key.testTag)) { Loading @@ -69,16 +73,18 @@ private class SceneScopeImpl( override fun <T> animateSharedValueAsState( value: T, key: ValueKey, element: ElementKey, element: ElementKey?, lerp: (T, T, Float) -> T, canOverflow: Boolean ): State<T> { val element = layoutImpl.elements[element] element?.let { key -> layoutImpl.elements[key] ?: error( "Element $element is not composed. Make sure to call animateSharedXAsState " + "Element $key is not composed. Make sure to call animateSharedXAsState " + "*after* Modifier.element(key)." ) } return animateSharedValueAsState( layoutImpl, Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt +4 −2 Original line number Diff line number Diff line Loading @@ -142,7 +142,9 @@ interface SceneScope { * * @param value the value of this shared value in the current scene. * @param key the key of this shared value. * @param element the element associated with this value. * @param element the element associated with this value. If `null`, this value will be * associated at the scene level, which means that [key] should be used maximum once in the * same scene. * @param lerp the *linear* interpolation function that should be used to interpolate between * two different values. Note that it has to be linear because the [fraction] passed to this * interpolator is already interpolated. Loading @@ -157,7 +159,7 @@ interface SceneScope { fun <T> animateSharedValueAsState( value: T, key: ValueKey, element: ElementKey, element: ElementKey?, lerp: (start: T, stop: T, fraction: Float) -> T, canOverflow: Boolean, ): State<T> Loading
packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt +2 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ class AnimatedSharedAsStateTest { val int by animateSharedIntAsState(targetValues.int, TestValues.Value1, key) val float by animateSharedFloatAsState(targetValues.float, TestValues.Value2, key) val dp by animateSharedDpAsState(targetValues.dp, TestValues.Value3, key) val color by animateSharedColorAsState(targetValues.color, TestValues.Value4, key) val color by animateSharedColorAsState(targetValues.color, TestValues.Value4, element = null) // Make sure we read the values during composition, so that we recompose and call // onCurrentValueChanged() with the latest values. Loading