Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a3ba8f1f authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Android (Google) Code Review
Browse files

Merge "Animate SceneTransitionLayout size" into main

parents e6584d79 f4898110
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -506,7 +506,10 @@ private inline fun <T> computeValue(

    // There is no ongoing transition.
    if (state !is TransitionState.Transition || state.fromScene == state.toScene) {
        return idleValue
        // Even if this element SceneTransitionLayout is not animated, the layout itself might be
        // animated (e.g. by another parent SceneTransitionLayout), in which case this element still
        // need to participate in the layout phase.
        return currentValue()
    }

    // A transition was started but it's not ready yet (not all elements have been composed/laid
+2 −1
Original line number Diff line number Diff line
@@ -2,9 +2,10 @@ package com.android.compose.animation.scene

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.unit.IntSize

interface DraggableHandler {
    fun onDragStarted(startedPosition: Offset, pointersDown: Int = 1)
    fun onDragStarted(layoutSize: IntSize, startedPosition: Offset, pointersDown: Int = 1)
    fun onDelta(pixels: Float)
    fun onDragStopped(velocity: Float)
}
+3 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.input.pointer.util.addPointerInputChange
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.util.fastForEach

@@ -60,7 +61,7 @@ internal fun Modifier.multiPointerDraggable(
    orientation: Orientation,
    enabled: Boolean,
    startDragImmediately: Boolean,
    onDragStarted: (startedPosition: Offset, pointersDown: Int) -> Unit,
    onDragStarted: (layoutSize: IntSize, startedPosition: Offset, pointersDown: Int) -> Unit,
    onDragDelta: (Float) -> Unit,
    onDragStopped: (velocity: Float) -> Unit,
): Modifier = composed {
@@ -83,7 +84,7 @@ internal fun Modifier.multiPointerDraggable(

        val onDragStart: (Offset, Int) -> Unit = { startedPosition, pointersDown ->
            velocityTracker.resetTracking()
            onDragStarted(startedPosition, pointersDown)
            onDragStarted(size, startedPosition, pointersDown)
        }

        val onDragCancel: () -> Unit = { onDragStopped(/* velocity= */ 0f) }
+14 −3
Original line number Diff line number Diff line
@@ -25,8 +25,9 @@ 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.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.intermediateLayout
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.zIndex
@@ -44,14 +45,24 @@ internal class Scene(
    var content by mutableStateOf(content)
    var userActions by mutableStateOf(actions)
    var zIndex by mutableFloatStateOf(zIndex)
    var size by mutableStateOf(IntSize.Zero)
    var targetSize 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
    @OptIn(ExperimentalComposeUiApi::class)
    fun Content(modifier: Modifier = Modifier) {
        Box(modifier.zIndex(zIndex).onPlaced { size = it.size }.testTag(key.testTag)) {
        Box(
            modifier
                .zIndex(zIndex)
                .intermediateLayout { measurable, constraints ->
                    targetSize = lookaheadSize
                    val placeable = measurable.measure(constraints)
                    layout(placeable.width, placeable.height) { placeable.place(0, 0) }
                }
                .testTag(key.testTag)
        ) {
            scope.content()
        }
    }
+12 −7
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
@@ -90,7 +91,7 @@ class SceneGestureHandler(

    internal var gestureWithPriority: Any? = null

    internal fun onDragStarted(pointersDown: Int, startedPosition: Offset?) {
    internal fun onDragStarted(pointersDown: Int, layoutSize: IntSize, startedPosition: Offset?) {
        if (isDrivingTransition) {
            // This [transition] was already driving the animation: simply take over it.
            // Stop animating and start from where the current offset.
@@ -126,14 +127,14 @@ class SceneGestureHandler(
        // we will also have to make sure that we correctly handle overscroll.
        swipeTransition.absoluteDistance =
            when (orientation) {
                Orientation.Horizontal -> layoutImpl.size.width
                Orientation.Vertical -> layoutImpl.size.height
                Orientation.Horizontal -> layoutSize.width
                Orientation.Vertical -> layoutSize.height
            }.toFloat()

        val fromEdge =
            startedPosition?.let { position ->
                layoutImpl.edgeDetector.edge(
                    layoutImpl.size,
                    layoutSize,
                    position.round(),
                    layoutImpl.density,
                    orientation,
@@ -513,9 +514,9 @@ class SceneGestureHandler(
private class SceneDraggableHandler(
    private val gestureHandler: SceneGestureHandler,
) : DraggableHandler {
    override fun onDragStarted(startedPosition: Offset, pointersDown: Int) {
    override fun onDragStarted(layoutSize: IntSize, startedPosition: Offset, pointersDown: Int) {
        gestureHandler.gestureWithPriority = this
        gestureHandler.onDragStarted(pointersDown, startedPosition)
        gestureHandler.onDragStarted(pointersDown, layoutSize, startedPosition)
    }

    override fun onDelta(pixels: Float) {
@@ -647,7 +648,11 @@ class SceneNestedScrollHandler(
            canContinueScroll = { true },
            onStart = {
                gestureHandler.gestureWithPriority = this
                gestureHandler.onDragStarted(pointersDown = 1, startedPosition = null)
                gestureHandler.onDragStarted(
                    pointersDown = 1,
                    layoutSize = gestureHandler.currentScene.targetSize,
                    startedPosition = null,
                )
            },
            onScroll = { offsetAvailable ->
                if (gestureHandler.gestureWithPriority != this) {
Loading