Status Update
Comments
jb...@google.com <jb...@google.com> #2
st...@gmail.com <st...@gmail.com> #3
Just to confirm that this is still not fixed in the beta04 releases. I updated the project to use: compose-animation (and the rest of the compose deps): 1.7.0-beta04 navigation: 2.8.0-beta04
And I still experience the exact same bug. The
st...@gmail.com <st...@gmail.com> #4
Sorry forgot to mention, this is also true for the current latest snapshots with ID "12028716".
The lifecycle looks to be updated properly, exactly due to the bug fix which was done in navigation beta04. But the shared element is still not rendering after starting and aborting a predictive back.
Video attached with the current behavior, after I've already once done the repro steps I describe in the original bug report message.
ti...@google.com <ti...@google.com> #5
Jeremy, could you help triage this please?
jb...@google.com <jb...@google.com> #6
I took another look at this and Navigation has all of the right information so I am thinking it is a SeekableTransition + SharedElement interaction. On the cancellation, NavHost
correctly calls AnimatedContent
finish after that, NavHost settles to the correct target state
I assumed that as long as the beta04
correctly got the SeekableTransitionState
to the correct target state then shared elements would be in the correct state as well. Does that need to be handled separately somehow? And if that is the case, could it be that this is part of animateTo
handle cancelation?
ti...@google.com <ti...@google.com> #7
Shared elements are not special animations from the perspective of Transition
.
Not sure if this has been fixed with George's recent fixes for SeekableTransition. George, could you help take a look please?
mo...@google.com <mo...@google.com> #8
I can reproduce this on tip-of-tree.
mo...@google.com <mo...@google.com> #9
Oscar and I discovered that the problem is in SharedTransitionScope
os...@google.com <os...@google.com>
st...@gmail.com <st...@gmail.com> #10
This is marked as fixed, however I just tested with the exact same repro project on snapshot 12176588 which is the current latest as of right now as I am typing this. What was fixed here, and how was it verified? Perhaps it would help to re-run the repro project I've submitted here on tip-of-tree to see that the broken behavior remains?
The repro project is here
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
App()
}
}
}
@Serializable
object A
@Serializable
object B
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
private fun App() {
val navController = rememberNavController()
SharedTransitionLayout {
Surface(modifier = Modifier.fillMaxSize()) {
NavHost(
navController,
A::class,
modifier = Modifier.fillMaxSize(),
) {
composable<A> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column {
Text("A: ${LocalLifecycleOwner.current.lifecycle.currentStateAsState()}")
Button({ navController.navigate(B) }) { Text("Go to B") }
SharedBox( this@composable)
}
}
}
composable<B> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column {
SharedBox( this@composable)
Text("B: ${LocalLifecycleOwner.current.lifecycle.currentStateAsState()}")
Button(dropUnlessResumed { navController.navigate(A) }) { Text("Go to A") }
}
}
}
}
}
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun SharedTransitionScope.SharedBox(
animatedVisibilityScope: AnimatedVisibilityScope,
modifier: Modifier = Modifier,
) {
Box(
modifier
.sharedElement(
rememberSharedContentState("SharedBox"),
animatedVisibilityScope,
)
.size(200.dp)
.background(Color.Red)
)
}
And the repro steps are shown in this newly attached video.
It's important to have it run on an Android version which does have predictive back support to experience the bug. I ran this on API level 35 for this video.
Could this be re-opened, or would you like me to open a new issue? What can I do to help you here?
os...@google.com <os...@google.com> #11
The fix is on the animation library, not the navigation library. Make sure to update that dependency from the snapshot. (androidx.compose:animation:animation)
st...@gmail.com <st...@gmail.com> #12
Hey, thanks a lot for the reply.
Can I safely assume that this dependency is androidx.compose.animation:animation
or even perhaps androidx.compose.animation:animation-android
?
The repro project is using
And I can still reproduce this problem exactly as the video shows. What else could I be doing wrong? Is the fix in the latest snapshots or released on the latest animation betas btw? Perhaps I should try the latest beta release instead?
os...@google.com <os...@google.com> #13
Sorry, my bad. It's not gonna be on the 1.7.0-SNAPSHOT.
Try
And then use compose = "1.8.0-SNAPSHOT"
I've locally confirmed it fixes the issue on Android 14, using predictive back.
os...@google.com <os...@google.com> #14
For reference, I changed these in your provided project.
libs.versions.toml:
[versions]
agp = "8.4.2"
kotlin = "2.0.0"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.4"
activityCompose = "1.9.1"
composeBom = "2024.06.00"
material3 = "1.3.0-beta05"
kotlinx-serialization = "1.7.1"
navigation = "2.8.0-SNAPSHOT"
compose = "1.8.0-SNAPSHOT"
#navigation = "2.8.0-beta06"
#compose = "1.7.0-beta06"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "compose" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "compose" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "compose" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "compose" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "compose" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4", version.ref = "compose" }
androidx-compose-animation = { group = "androidx.compose.animation", name = "animation", version.ref = "compose" }
androidx-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
androidx-navigation-common = { module = "androidx.navigation:navigation-common", version.ref = "navigation" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation" }
androidx-navigation-runtime = { module = "androidx.navigation:navigation-runtime", version.ref = "navigation" }
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
composeCompilerGradlePlugin = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
sttings.gradle.kts:
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven(url = "https://androidx.dev/snapshots/builds/12176908/artifacts/repository")
google()
mavenCentral()
}
}
rootProject.name = "predictive-navigation-repro"
include(":app")
os...@google.com <os...@google.com> #15
FWIW, we cherry-picked the fix for the next 1.7.0 release.
I think this page will get updated with details once it's released.
st...@gmail.com <st...@gmail.com> #16
Oh 1.8 snapshot, I did not actually know that this was available yet!
Hey by the way, I really appreciate your communication here, and even taking the effort to paste your changes to my project! I just tested myself too and this is indeed fixed as you said!
So since this was now cherry picked this will even be in the next 1.7 beta release, that's great news. Thanks for helping me out here!
pr...@google.com <pr...@google.com> #17
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.compose.animation:animation:1.7.0-beta07
androidx.compose.animation:animation-android:1.7.0-beta07
androidx.compose.animation:animation-desktop:1.7.0-beta07
Description
Component used: Navigation Version used: 2.8.0-alpha05 through 2.8.0-beta03 and 2.8.0-SNAPSHOT Devices/Android versions reproduced on: Android 15 VanillaIceCream(AP31.240426.023.B4)
Repro project attached as a zip, there is a video showcasing the bug. The repo is also public herehere toohttps://github.com/StylianosGakis/navigation-predictive-back-breaking-shared-element if you prefer to check it out this way.
This may or may not be related to https://issuetracker.google.com/issues/346608857 since this also happens after predictive back starts and is cancelled.
Steps to reproduce:
My assumption here is that the AnimatedVisibilityScope is somehow not cleaned up properly resulting in this broken behavior. But that is just my assumption, the repro project should help you understand the real issue behind all this.