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

Commit fceb6bdc authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Respect animationSpec for predictive back transition in STL" into main

parents a9910754 fac45418
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -127,7 +127,16 @@ private class PredictiveBackTransition(
        return coroutineScope
            .launch(start = CoroutineStart.ATOMIC) {
                try {
                    if (currentScene == toScene) {
                        animatable.animateTo(targetProgress, transformationSpec.progressSpec)
                    } else {
                        // If the back gesture is cancelled, the progress is animated back to 0f by
                        // the system. But we need this animate call anyways because
                        // PredictiveBackHandler doesn't guarantee that it ends at 0f. Since the
                        // remaining change in progress is usually very small, the progressSpec is
                        // omitted and the default spring spec used instead.
                        animatable.animateTo(targetProgress)
                    }
                } finally {
                    state.finishTransition(this@PredictiveBackTransition, scene)
                }
+34 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.compose.animation.scene

import androidx.activity.BackEventCompat
import androidx.activity.ComponentActivity
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.rememberCoroutineScope
@@ -59,7 +61,23 @@ class PredictiveBackHandlerTest {

    @Test
    fun testPredictiveBack() {
        val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) }
        val transitionFrames = 2
        val layoutState =
            rule.runOnUiThread {
                MutableSceneTransitionLayoutState(
                    SceneA,
                    transitions =
                        transitions {
                            from(SceneA, to = SceneB) {
                                spec =
                                    tween(
                                        durationMillis = transitionFrames * 16,
                                        easing = LinearEasing
                                    )
                            }
                        }
                )
            }
        rule.setContent {
            SceneTransitionLayout(layoutState) {
                scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) }
@@ -88,12 +106,27 @@ class PredictiveBackHandlerTest {
        assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
        assertThat(layoutState.transitionState).isIdle()

        rule.mainClock.autoAdvance = false

        // Start again and commit it.
        rule.runOnUiThread {
            dispatcher.dispatchOnBackStarted(backEvent())
            dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
            dispatcher.onBackPressed()
        }
        rule.mainClock.advanceTimeByFrame()
        rule.waitForIdle()
        val transition2 = assertThat(layoutState.transitionState).isTransition()
        // verify that transition picks up progress from preview
        assertThat(transition2).hasProgress(0.4f, tolerance = 0.0001f)

        rule.mainClock.advanceTimeByFrame()
        rule.waitForIdle()
        // verify that transition is half way between preview-end-state (0.4f) and target-state (1f)
        // after one frame
        assertThat(transition2).hasProgress(0.7f, tolerance = 0.0001f)

        rule.mainClock.autoAdvance = true
        rule.waitForIdle()
        assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
        assertThat(layoutState.transitionState).isIdle()