Atul Gupta
09/15/2024, 9:47 AMSharedTransitionLayout {
Scaffold {
bottomBar = { if (fullScreen) { BottomBarUi() } } // bottom bar is shared as few screens shares the same bottom
} {
NavHost() //Here my other screens are present
}
}
Now I am facing the issue, as I want to animate the BottomBarUi
but in that scope I don't have AnimatedVisibilityScope
as that is present inside NavHost
-> composable
Is there anything wrong I am doing? Can I somehow wrap the BottomBarUi
with a AnimatedVisibility
and shared the top AnimatedVisibilityScope
with NavHost so that animation happens in sync?Stylianos Gakis
09/15/2024, 2:55 PMAtul Gupta
09/15/2024, 3:01 PMSharedTransitionLayout {
// Here my other screens are present which are full screen
NavHost {
compoasble<Home> {
// this used to be at the top now moved it inside the Home which is now NEW NESTED DESTINATION
HomeScaffold {
bottomBar = { if (fullScreen) { BottomBarUi() } }
} {
navigation(Feed) { // other bottom sheet UIs}
}
}
}
}
This I am following with Jetsnack app
Though I am surprised they are using a new NavHost instead of using the navigation
function which creates nested nav.
I might encounter some issue then will revert to follow Jetsnack exactlyAtul Gupta
09/15/2024, 6:14 PMAnimatedVisibilityScope
😔
Now trying https://kotlinlang.slack.com/archives/C06CS4UCQ10/p1719560459770529?thread_ts=1719554859.324029&cid=C06CS4UCQ10 🥱Stylianos Gakis
09/16/2024, 7:45 AMI am surprised they are using a new NavHost instead of using theWhere do they do that? It's probably an oversight, it is quite rare where you need a second NavHost.function which creates nested nav.navigation
Atul Gupta
09/16/2024, 8:02 AMNavHost { // this NavHost for full screen
composable<FullScreenUiModel> { FullScreenU() }
composable<BottomBarUiModel> { BottomBarUi() }
}
Now I followed the guide for bottom sheet at https://developer.android.com/develop/ui/compose/navigation#bottom-nav which shows code like below for implementing the BottomBar, which I thought will be the code for the BottomBarUi
@Composable
fun BottomBarUi() {
Scaffold(
bottomBar = {
BottomNavigation { }
}
) { innerPadding ->
// here I though my second NavHost will be present
NavHost(navController, startDestination = Profile, Modifier.padding(innerPadding)) {
composable<Profile> { ProfileScreen(...) }
composable<Friends> { FriendsScreen(...) }
}
}
}
Also in Jetsnack app, you can see the first NavHost at JetsnackApp.kt (this has the top level NavHost and has MainContainer
containing the bottom bar UI and full screen SnackDetail
screen) and second NavHost at JetsnackApp.kt MainContainer
composable this contains the Feed screen(Home), search screen, cart screen and profile screen(basically bottom bar UI screens)Atul Gupta
09/16/2024, 8:04 AMnavigation
to create a nested nav graph but when I was adding this inside a Scaffold
in content
composable lambda I was not able to make it work. But since I tried too many things very rapidly I was not sure whether it was mistake on my part or it is not suppose to work like thatStylianos Gakis
09/16/2024, 8:10 AM@Composable
fun App() {
NavHost(navController) {
composable<Profile> { ProfileScreen(...) }
composable<Friends> { FriendsScreen(...) }
}
}
fun ProfileScreen() {
Scaffold(bottomBar = BottomBar(...)) {
ScreenContent()
}
}
fun FriendsScreen() {
Scaffold(bottomBar = BottomBar(...)) {
ScreenContent()
}
}
fun BottomBar(selected: Int, ...) {
Box(Modifier.sharedElement(...))
}
Atul Gupta
09/16/2024, 8:11 AMbottomNavComposable
which has composable { Scaffold { content() } }
kind of structure
2. Using single NavHost
3. Shared the Scaffold, fab and bottom bar with sharedElement
unique keys which is present in bottomNavComposable
Scaffold
like you mentioned
4. Added some .animateEnterExit()
in the bottom bar
But it is also showing few issuesAtul Gupta
09/16/2024, 8:15 AMthree_iteration
video(this happen very rarely and also happen with Jetsnack app))
2. Screen flashes white(I am not sure this might be due usage of Surface but still debugging it)
3. Bottom bar height shift when changing the bottom bar items(shown in first try in bottom_bar_shift
)Atul Gupta
09/16/2024, 8:16 AMAtul Gupta
09/16/2024, 8:24 AMStylianos Gakis
09/16/2024, 8:25 AM1. sometimes instead of expand it goes side ways this happened in the video in the third trial in theIf you are coming from one screen without the bottom bar then it will have just the animation of the rest of the screen right? This is what you're preventing with .animateEnterExit, but doesn't always do what you want it to?video(this happen very rarely and also happen with Jetsnack app))three_iteration
White flashYeah do not use Scaffold TBH if you can avoid it, no reason to introduce subcomposition in this mix.
JumpLooks like something to do with the insets there, they are not there for a frame so the UI jumps somehow. Not sure if this has to do with subcomposition, shared elements or whatever. I'd try without Scaffold as a first step and take it from there.
Stylianos Gakis
09/16/2024, 8:27 AMsee the last animation which goes sidewaysI've seen this bug before in some older navigation/animation dependency version combos, but I think it also had to do with the fact that the child of NavHost was not always defining
fillMaxSize()
, could you double check that you are doing that properly in all destinations?
@Composable
fun App() {
NavHost(navController) {
composable<Profile> { ProfileScreen(Modifier.fillMaxSize(), ...) }
composable<Friends> { FriendsScreen(Modifier.fillMaxSize(), ...) }
}
}
Just to be sure this is not it.
Also are you on latest stable for compose animations + androidx.navigation?Atul Gupta
09/16/2024, 8:34 AMfillMaxSize
though again this sounds like a bug 😅
My vesions as follow
kotlin = "2.0.20"
jetbrainsCompose = { id = "org.jetbrains.compose", version = "1.7.0-beta01" }
androidx-navigationCompose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version = "2.8.0-alpha09" }
This is KMM project so compose ui is coupled with jetbrains pluginAtul Gupta
09/16/2024, 8:41 AMIf you are coming from one screen without the bottom bar then it will have just the animation of the rest of the screen right? This is what you’re preventing with .animateEnterExit, but doesn’t always do what you want it to?
but doesn't always do what you want it to?
I have added animateEnterExit
but this is also not working shows different results in each run(I think Scaffold is really messing everything here). See also bottom bar when coming back to list shift slightly this could be due to insets as you mentionedAtul Gupta
09/16/2024, 9:56 AMStylianos Gakis
09/16/2024, 2:36 PMAtul Gupta
09/16/2024, 2:38 PMAtul Gupta
09/16/2024, 3:55 PMScaffold
with Surface { Colomnu { } }
but bugs #1 and #2 are still happening #3 got fixed though not because of the removal of the Scaffold but the reordering of the modifiers(earlier I was using sharedElement
first then animateEnterExit
) now with animateEnterExit first and sharedElement later fixed the bottom sheet animation
Not ideal still but attaching the video(this is with Scaffold and with fillMaxWidth) 🙂Stylianos Gakis
09/16/2024, 5:52 PMAtul Gupta
09/16/2024, 5:56 PMAtul Gupta
09/16/2024, 6:27 PMAtul Gupta
09/16/2024, 6:30 PMAtul Gupta
09/16/2024, 7:57 PMNavHost
was enclosed in a single Scaffold
which is single Surface
inside and since my other screens didn't have any Surface
hence no bg and hence no animationStylianos Gakis
09/16/2024, 8:15 PMSurface(backgroundColor) {
NavHost()
}
So that no matter what, the right background color is added around the entire app, despite whatever the NavHost destination might show.
So tl;dr on this, no problems were with shared transitions then, and you gotta fix your app's problems without it, and then move on to implement it too and see if that by itself brings any issues.
Did I get this right?Atul Gupta
09/16/2024, 8:44 PMDoris Liu
09/17/2024, 12:26 AManimateEnterExit
needs to be before sharedElement
. Otherwise, even when shared element keeps the UI in place, its child (in this case animateEnterExit
would move the content in unexpected ways). Are you using sliding or shrinking/expanding for animateEnterExit
?Atul Gupta
09/17/2024, 9:30 AManimateEnterExit
contains the below code similar to Jetsnack app
.animateEnterExit(
enter = fadeIn(nonSpatialExpressiveSpring()) + slideInVertically(
spatialExpressiveSpring()
) { it },
exit = fadeOut(nonSpatialExpressiveSpring()) + slideOutVertically(
spatialExpressiveSpring()
) { it }
)
would move the content in unexpected ways
Yes I think that was happening.. as Bottom bar animating in weird waysAtul Gupta
09/17/2024, 12:17 PMOutlinedTextField
stays for a bit longer and the list item appears after a while. Attached is a video where the last detail to the list animation shows that). This could be an issue on my end(or might be due to usage of OutLineTextField
) and I am still debugging that
2. Issue #1 mentioned at https://kotlinlang.slack.com/archives/C04TPPEQKEJ/p1726474510829169?thread_ts=1726393625.250919&cid=C04TPPEQKEJ is still there(not shown in this video). But currently, I am pretty sure this is not related to the shared element.Doris Liu
09/17/2024, 6:34 PMsometimes the outlineIs each item also a sharedBounds? Is there any fade specified for the enter/exit of the OutlinedTextFields/sharedBounds? If there's no fade, you'd need to make sure the outgoing details page containing text fields to have a lower zIndex so that it doesn't render on top of the list item.stays for a bit longer and the list item appears after a whileOutlinedTextField
Atul Gupta
09/18/2024, 9:49 PMsharedElement
which with just required params(i.e., with all default values left untouched)
> Is there any fade specified for the enter/exit of the OutlinedTextFields/sharedBounds?
fade is only applied to the bound of list item vs item detail(not in individual shared elements). Even removing those doesn't solve the bounding box appearing issue
One thing I noticed is that if I wait for the list item -> detail animation to finish(you can observe the FAB disappearance for the animation finished state) before pressing the back button issue doesn't appear. I have attached two more videos one with a wait and one without a wait(the issue appears in this video). Now I have something to debug this further
BTW thanks all for helping me this much 🙂Doris Liu
09/19/2024, 5:05 PMOutlinedTextFields
shared elements also? How are they supposed to fade out?Atul Gupta
09/20/2024, 8:23 AMOutlinedTextFields
is like below
OutlinedTextField(
modifier = Modifier
.sharedElement(
state = rememberSharedContentState("key_name"),
animatedVisibilityScope = this@AnimatedVisibilityScope,
)
.fillMaxWidth()
.focusProperties {
next = focusRequesterName
down = focusRequesterName
}
.focusRequester(focusRequesterAmount),
value = value,
onValueChange = { value = it },
)
So they are sharedElement
with no animation on it.
Overall container of list and detail page use Spring animation though
That timing discrepancy may be what we see here.Is there a way to fix this?
Stylianos Gakis
09/20/2024, 9:31 AMAtul Gupta
09/20/2024, 10:34 AMI feel like your problems comes from something unrelated still
though I am not denying the fact that the problem can be from smth else as well)
In this project, I am not using any custom animation just the default ones
Also, in the video, you will see the first two animations(from list item to detail) with significant delay to allow the animation to finish, while in the last two, you will see the animation where I interrupted the animation(so you will observe the bounding boxes appearing on the top of list item UI).
I always want my animation to be consistent and like how it ran for the first two iterationAtul Gupta
10/09/2024, 12:36 PMDoris Liu
10/11/2024, 11:03 PMDoris Liu
10/11/2024, 11:06 PMAnimatedContent
, I don't see the issue. But I do see the issue with NavHost. The biggest difference between the two is the latter uses a seekable transitionAtul Gupta
10/12/2024, 10:49 AMIt seems like a SeekableTransition specific issue.
Thanks for the reply.. Let me file it. I will add all those detailsAtul Gupta
10/12/2024, 11:27 AMAtul Gupta
11/23/2024, 4:08 PMDoris Liu
11/23/2024, 8:45 PMAtul Gupta
11/25/2024, 11:51 AMAtul Gupta
11/25/2024, 5:06 PMDoris Liu
12/02/2024, 7:29 PMDoris Liu
12/03/2024, 9:34 PM