diff --git a/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/DefaultStackAnimation.kt b/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/DefaultStackAnimation.kt index bcb4c4ac0..0a7484b6a 100644 --- a/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/DefaultStackAnimation.kt +++ b/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/DefaultStackAnimation.kt @@ -57,10 +57,10 @@ internal class DefaultStackAnimation( currentStack = stack val updateItems = - if (stack.active.key == oldStack.active.key) { - items.keys.singleOrNull() != stack.active.key - } else { - items.keys.toList() != stackKeys + when { + stack.active.key == oldStack.active.key -> items.keys.singleOrNull() != stack.active.key + items.size == 1 -> items.keys.single() != stack.active.key + else -> items.keys.toList() != stackKeys } if (updateItems) { diff --git a/extensions-compose-experimental/src/jvmTest/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/PredictiveBackGestureTest.kt b/extensions-compose-experimental/src/jvmTest/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/PredictiveBackGestureTest.kt index 801785c2d..3276498d1 100644 --- a/extensions-compose-experimental/src/jvmTest/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/PredictiveBackGestureTest.kt +++ b/extensions-compose-experimental/src/jvmTest/kotlin/com/arkivanov/decompose/extensions/compose/experimental/stack/animation/PredictiveBackGestureTest.kt @@ -1,5 +1,7 @@ package com.arkivanov.decompose.extensions.compose.experimental.stack.animation +import androidx.compose.animation.EnterExitState +import androidx.compose.animation.core.animateFloat import androidx.compose.material.Text import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -20,6 +22,7 @@ import com.arkivanov.essenty.backhandler.BackEvent import org.junit.Rule import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFalse @Suppress("TestFunctionName") @OptIn(ExperimentalDecomposeApi::class) @@ -282,6 +285,44 @@ class PredictiveBackGestureTest { composeRule.onNodeWithText("3").assertTestTagToRootDoesNotExist { it.startsWith(TEST_TAG_PREFIX) } } + @Test + fun GIVEN_three_children_in_stack_WHEN_predictive_back_finished_THEN_previous_child_not_animated_after_pop() { + var stack by mutableStateOf(stack("1", "2", "3")) + val values = ArrayList() + + val animation = + DefaultStackAnimation( + onBack = { + values.clear() + stack = stack.dropLast() + } + ) + + + composeRule.setContent { + animation(stack, Modifier) { + val float by transition.animateFloat { state -> + when (state) { + EnterExitState.PreEnter -> 0F + EnterExitState.Visible -> 1F + EnterExitState.PostExit -> 0F + } + } + + if (it.configuration == "2") { + values += float + } + } + } + + backDispatcher.startPredictiveBack(BackEvent(progress = 0F)) + composeRule.waitForIdle() + backDispatcher.back() + composeRule.waitForIdle() + + assertFalse(values.any { it < 1F }) + } + private fun DefaultStackAnimation(onBack: () -> Unit): DefaultStackAnimation = DefaultStackAnimation( disableInputDuringAnimation = false,