Another basic question - what pattern are people u...
# compose-android
m
Another basic question - what pattern are people using when implementing a bottom navigation bar with compose nav? 1. Bottom nav bar exists in the Composable hierarchy above the
NavHost
that navigates between tabs 2. Each tab inside the
NavHost
Composes the bottom nav bar themselves My main consideration is I want to be able to navigate from each of those tabs to other deeper “fullscreen” screens without the nav bar visible
s
If you are ok with using some experimental apis make the bottom var a common UI element you can just put inside each screen that needs it. And make it a shared element with the same ID. Then you'll get a persistent bottom bar for the screens that have it, and it will simply animate away just like the rest of the screen would when navigating towards screens that don't have it. Bonus that now you can intercept those clicks and do screen-specific interactions much much easier than when it is one global UI element above the NavHost
👀 2
If you don't want to use shared element apis, then one global one is the way to go, and you manage when it's shown or not shown by looking at the NavControllers current destination. But that makes some transitions tricky and doesn't easily let you do screen specific interactions when let's say you click on the item of the already highlighted tab.
m
you manage when it’s shown or not shown by looking at the NavControllers current destination
This is what I was scared of - I’d much rather not hardcode the screens that should display it into the enclosing screen. It feels wrong for the parent Composable to manage it outside of configuring the
NavHost
, but maybe my instincts around component responsibilities aren’t right here.
you click on the item of the already highlighted tab.
Do you mean you’d end up having a transition animation in this case, even though it’s the same tab? I’ve seen suggestions to use
launchSingleTop
which I thought would resolve that, but I haven’t tested it. e.g.
Copy code
BottomNavigation {
        items.forEach { screen ->
            BottomNavigationItem(
                icon = { /* Your Icon Here */ },
                label = { Text(screen.capitalize()) },
                selected = navController.currentDestination?.route?.startsWith(screen) == true,
                onClick = {
                    navController.navigate(screen) {
                        popUpTo(navController.graph.findStartDestination().id) {
                            saveState = true
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                }
            )
        }
    }
The shared element APIs sound very interesting. I’ll take a look into those, thanks!
s
I meant more like scenarios where clicking on the same tab as you are should scroll to the first item in the index, or refresh your content and other such screen specific interactions
👌 1
c
I think the docs for navigation specify this case (if im understanding you correctly). lemme try to find it
i always just copy-pasta that in about every app i work on lol
s
Yeah that one is the way to go in a world without shared elements. We do that same, albeit without a Scaffold to avoid subcompositions for no reason.
c
Oooh. Should I get rid of my scaffold too? "world without shared elements"? 🙈 should i change things up since I do want to be open to having SET?
This https://kotlinlang.slack.com/archives/CJLTWPH7S/p1680837880604599?thread_ts=1680773211.418409&cid=CJLTWPH7S is what will be possible with shared elements. Till those are there though, not much to do to prepare I suppose. You can do the work then.
c
thanks. i will give those a look later tonight!