I have a slight issue with compose navigation + an...
# compose
c
I have a slight issue with compose navigation + animations. I'd like to apply contentPadding from my top-level scaffold to all child composables. I've done this by wrapping my navHost in a box with contentPadding applied to it Src. This works fine. There are cases where I'd like to hide my BottomNav bar on navigation. I do this via AnimatedVisibility on the BottomBar composable on my scaffold. This works, but the issue is upon animating away the padding I've applied on all my child composables remains until
PaddingValues.calculateBottomPadding
finishes updating. So it looks like The content of the bottomNav animates down but there's now a blank white Bar where the bottom nav used to be for about 1 second. (This is the padding lagging behind). Is there a way to animate the bottom bar to be gone alongside the padding on the wrapped NavHost? Or should I apply the bottomBar padding to every top level composable?
s
So basically
calculateBottomPadding
returns the same value while the BottomNav (which consumes the insets when it exists) is animating out, and the moment it’s animated away, it no longer consumes those insets and then those children can use that padding. Do I understand this right?
c
Hey 👋 not quite. The bottomNav doesn't consume any insets since it's part of the scaffold. I think it probably partly generates that
calculateBottomPadding
value based on its height. Since it animates out and changes its height to 0 then
calculateBottomPadding
changes to 0 eventually. The issue is that the bottomNav animates first, but
calculateBottomPadding
will run afterwards so you're left with a blank white space where the BottomNav used to be for a second. I'll see if I can take a picture
a
Hello there! I had the exact same problem you're describing. I haven't found a better solution yet than to set the paddingValues programmatically observing whether the TransitionState of the AnimatedVisibility was idle and if the current destination is a bottom bar destination or not. The logic for the Box's modifier ended up being as follows:
Copy code
modifier =
if (isBottomBarDestination || !bottomBarTransitionState.isIdle)
    Modifier
else
    Modifier.padding(paddingValues)
Hope this helps!
c
Ah! I forgot about
MutableTransitionState
. That does indeed solve the blank white space left behind by padding gratitude thank you . After you do this though it looks like when you navigate your composable 'jitters' for a second. This is because we're changing viewport's size it's being displayed in so after the size changes it then resizes which looks wonky.. does this not happen for you?
Omg. I figured out our problem... It was a composition problem of course 🤦 I was doing what you were except for how I was changing the transition state. We have our bottomNav visible state in our viewModel's uiState. So I was checking on destination change if we're supposed to show the bottom nav, then sending that up to the viewModel to emit a new state but that's too late. I needed to set the transition state immediately on navigation when I knew so it's in the same frame as navigation. Not one recomposition later. Looks good now thanks for steering me in this direction!
s
I gotta admit I'm still not 100% following what it is that you're describing since you didn't send a video after all, but I can share with you what I've done to make the change of the insets while the bottom nav is leaving the screen. It's basically this modifier here https://github.com/HedvigInsurance/android/blob/develop/app/app/src/main/kotlin/com/hedvig/app/feature/loggedin/ui/LoggedInActivity.kt#L332 Our nav bar showing or not is determined from
hedvigAppState.shouldShowBottomBar
. so as that changes and the bar animates out, I'm also animating the amount of insets that we're consuming. As that is animated, the content doesn't jump anywhere, the bottom nav animates down while at the same time we're giving more of the insets back to the content which would animate them up, together they make this transition smooth.
👍 2
c
Hey, sorry. I tried to take a screenshot of the issue but it happens within 1 second and was very hard to time with Android Studio. Looking at your code that makes a lot of sense and that 100% would work! I think the only difference is we're using a scaffold which means it has insets given to us in the content param. Not something we can customize. We could rework things to be similar to what you did but that'd be a big lift at this point. Thanks for sharing how you do it though. Looks pretty clean
1
s
An idea. Don't use scaffold 😅
But for real, why are you using the scaffold there, do you have a fab or a snackbar hosted there?
c
Yes we do 🙂
a
I'm glad to have helped Chris, cheers!
fist bump 1
s
Another idea would be to copy paste the scaffold internals and play with the insets yourself, do it exactly the way you want it to be. But just saying, us not using a scaffold top level was one of the good decisions we've made.
c
Noted. Will definitely look at other alternatives 👍
v
Styllanos, thank you for your solution! I've ran in to the same problem, using the Scaffold: when navigating to the destination without AppBar the new screen would take smaller space as it has AppBar, then the navController reports new screen, AppBar hides and the new destination takes up full space without AppBar, and it looks janky for a second. Gonna try your solution tomorrow :)
s
Give it a shot yeah! Please do tell if it works for you after all 😊
❤️ 1