[go: nahoru, domu]

Merge "Fix a regression in Crossfade related to states restoration" into androidx-main
diff --git a/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/CrossfadeTest.kt b/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/CrossfadeTest.kt
index a73246b..cb3bb00 100644
--- a/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/CrossfadeTest.kt
+++ b/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/CrossfadeTest.kt
@@ -22,12 +22,15 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.saveable.rememberSaveableStateHolder
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithText
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
+import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
 import org.junit.Rule
 import org.junit.Test
@@ -151,6 +154,56 @@
         rule.onNodeWithText(Second).assertExists()
     }
 
+    @Test
+    fun crossfadeTest_rememberSaveableIsNotRecreatedForScreens() {
+        rule.mainClock.autoAdvance = false
+
+        val duration = 100
+        var showFirst by mutableStateOf(true)
+        var counter = 1
+        var counter1 = 0
+        var counter2 = 0
+        rule.setContent {
+            val saveableStateHolder = rememberSaveableStateHolder()
+            Crossfade(
+                showFirst,
+                animationSpec = TweenSpec(durationMillis = duration)
+            ) {
+                saveableStateHolder.SaveableStateProvider(it) {
+                    if (it) {
+                        counter1 = rememberSaveable { counter++ }
+                    } else {
+                        counter2 = rememberSaveable { counter++ }
+                    }
+                }
+            }
+        }
+
+        rule.mainClock.advanceTimeByFrame() // Kick off the animation
+        rule.mainClock.advanceTimeBy(duration.toLong())
+
+        rule.runOnUiThread {
+            showFirst = false
+        }
+
+        rule.mainClock.advanceTimeBy(duration.toLong())
+        rule.mainClock.advanceTimeByFrame()
+        rule.mainClock.advanceTimeByFrame() // Wait for changes to propagate
+
+        // and go back to the second screen
+
+        rule.runOnUiThread {
+            showFirst = true
+        }
+
+        rule.mainClock.advanceTimeBy(duration.toLong())
+        rule.mainClock.advanceTimeByFrame()
+        rule.mainClock.advanceTimeByFrame() // Wait for changes to propagate
+
+        assertEquals(1, counter1)
+        assertEquals(2, counter2)
+    }
+
     companion object {
         private const val First = "first"
         private const val Second = "second"
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Crossfade.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Crossfade.kt
index 298142e..6a8aec4 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Crossfade.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/Crossfade.kt
@@ -67,13 +67,11 @@
         items.clear()
         keys.mapTo(items) { key ->
             CrossfadeAnimationItem(key) {
-                key(key) {
-                    val alpha by transition.animateFloat(
-                        transitionSpec = { animationSpec }
-                    ) { if (it == key) 1f else 0f }
-                    Box(Modifier.alpha(alpha = alpha)) {
-                        content(key)
-                    }
+                val alpha by transition.animateFloat(
+                    transitionSpec = { animationSpec }
+                ) { if (it == key) 1f else 0f }
+                Box(Modifier.alpha(alpha = alpha)) {
+                    content(key)
                 }
             }
         }
@@ -83,7 +81,11 @@
     }
 
     Box(modifier) {
-        items.fastForEach { it.content() }
+        items.fastForEach {
+            key(it.key) {
+                it.content()
+            }
+        }
     }
 }