Is it normal to have nested `NavHost` s? Or should...
# compose
z
Is it normal to have nested
NavHost
s? Or should the entire graph be defined at the top level?
a
both are valid options, depends on your use case
only the top level navigations (like the bottom nav items) should be top level
z
is having bottom nav at a lower level a no-no?
i
There's very, very, very few cases where the correct solution is to nest nav hosts. Generally, just putting top level UI behind an if statement around your current destination is the better approach
z
do you have a psuedo code example of that?
my root view is a list of events a user has been invited to/is attending. and once an event is selected each event has a bottom nav view to break the event up into "what are we doing/what do we need to bring/chat"
i
You'd same the approach as any other UI, like the bottom nav in the docs: https://developer.android.com/jetpack/compose/navigation#bottom-nav
Copy code
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)
if (currentRoute != "login") {
}
That seems like something you'd use tabs for FWIW
Multiple sibling screens about one subject vs bottom nav which is for separate things
z
yeah that's a good point
i
And for tabs, you'd want to be using a pager, not a nav host
z
i kinda see the event page as the core of the application and each "tab" offers a lot of functionality and child pages
so I may have just gotten too focused on the visual aspect of having it on the bottom
i
Maybe
But yes, on a technical level, nested nav hosts are a supported thing. For example, you could have each tab have its own nav host to navigate through multiple sub screens
z
yeah is that the "magic" the bottom nav provides?
i'll dig in and sort it out but thank you again for the insight! i love compose
m
Ian, would you include scoping in the very few cases where nested nav graphs are needed? e.g. if I wanted to have a
LoginRepository
scoped to a login flow, I’d create a nested graph and scope the LoginRepo to its VM
i
That's appropriate for a nested graph, sure, but not a nested nav host, which was what we were talking about here.
Personally, I'd think you'd want a login source of truth to be available on any destination, be it the login destinations for writing into it or other destinations to check who the logged in user is (and redirect to login as needed as per the conditional nav guide)
m
For login/user information I’d have a
UserRepository
that can be scoped to the
Application
. However, for something like a
LoginRepository
that is in charge of making the auth calls, I just want it in memory for a short period of time (but potentially reusable across multiple login screens)
Sorry, I conflated nested graphs with nested nav hosts. I’m not quite sure what’s the difference between them to be honest. In Compose, in order to create a nav graph, you need a
NavHost
. right?
My question assumes that
navGraphViewModels
works in Compose navigation but I’m not sure about it
i
Ah, yeah if you have a separate
UserRepository
, that certainly makes sense
Compose Navigation supports nested graphs via the
navigation
tag in the DSL. Yes, with a nested graph, you can scope ViewModels, etc. at the graph level. We're still working on what a nice API for that would look like, but you can see an example in this answer: https://stackoverflow.com/a/64961032/1676363
m
Awesome 🙂 thanks!
a
Ohh, I got confused with that as well. Good to know
j
We’re still working on what a nice API for that would look like, but you can see an example in this answer
@Ian Lake is there any update for this use case (i.e. scoping a VM to a nested nav graph)? Has a public API landed?
Copy code
hiltNavGraphViewModel()
Is now deprecated in favor of
hiltViewModel()
but it doesn’t seem it supports nested nav graph scoping yet. Should we still apply the temp solution at: https://stackoverflow.com/a/64961032/1676363 ?
i
val sharedViewModel = hiltViewModel(navController.getBackStackEntry("nested_nav"))
works just fine
🙏 1