Navigation Host Composables
Navigation Host Composables work as the holder for your screens and it's where they will be displayed.
Compose destinations has a recommended way to set up your NavHosts
and an alternative one. If you are not sure which to use and don't have much experience with Compose Navigation, go with the recommended DestinationsNavHost way. On the other hand, if you have a lot of experience with vanilla Compose Navigation and just want the type safety of Compose Destinations, you might prefer to use NavHost / AnimatedNavHost.
DestinationsNavHost
Compose Destinations has a "NavHost-like" Composable that you can use as a base for all your screens.
It internally calls the Compose Navigation NavHost
but automatically adds all @Destination
annotated Composables of a given NavGraph
instance to the NavHost. When a destination gets navigated to, it calls the corresponding generated Content
method which prepares the navigation arguments and calls your annotated Composable.
Most times, using it is as simple as:
DestinationsNavHost(navGraph = NavGraphs.root)
NavGraphs
is a generated object that contains the definition of all your navigation graphs and their destinations. By default, all annotated composable will belong to the "root" navigation graph. But you can customize this however you want. Read more here
However, you can override some defaults:
-
navGraph: NavGraphSpec
- By defaultNavGraphs.root
, but it can change depending on your navigation graphs setup. Only destinations that belong to this navigation graph or its nested navigation graphs can be navigated to using theNavController
connected to this navigation host. -
modifier: Modifier
- modifier applied to this Composable. It affects the screen Composable. -
startRoute: Route
: used to override the start route set in theNavGraph
"startRoute" parameter at runtime. If you have some condition upon which you want to start on some other screen, then pass it explicitly with this parameter.Route
is an interface only implemented byDestination
andNavGraph
, since both are valid to start at (if you pass aNavGraph
then thatNavGraph
's start destination will be the first shown). -
engine: NavHostEngine
- this is the engine that will do all the composable registering in the NavHost. The only reason to override the default here is when you're usinganimations-core
, i.e, when you want to animate between screens or have Bottom Sheet destinations. If that is your case, then callrememberAnimatedNavHostEngine
and pass the result here. Read more here -
navController: NavHostController
: If you need to get a hold of theNavController
, you can userememberAnimatedNavController
if you're usinganimations-core
and the normalrememberNavController
if you are not. -
dependenciesContainerBuilder
offers aDependenciesContainerBuilder
where you can add dependencies by their class viacom.ramcosta.composedestinations.navigation.dependency()
. The lambda will be called when a Composable screen gets navigated to andDependenciesContainerBuilder
also implementscom.ramcosta.composedestinations.manualcomposablecalls.DestinationScope
so you can access all information about whatDestinationSpec
is being navigated to. Read more here. -
manualComposableCallsBuilder: ManualComposableCallsBuilder.() -> Unit
: offers aManualComposableCallsBuilder
scope where you can make manual calls to specific Destination Composables which belong to thenavGraph
passed in here. This can be useful if you need to pass non-navigation arguments to those specific Composables which the library cannot provide. Read more here
Vanilla NavHosts
If you are experienced with using Compose Navigation, you may prefer using the same NavHost Composables. This is mainly a preference thing, but, in my opinion, having a NavGraphs
object where you can check your app's destinations and where they belong without all the clutter from the arguments, Composables, etc is beneficial. Besides, being able to quickly and safely check at runtime which navigation graph some route belongs to and getting the Destination
from the NavBackStackEntry
can come in handy.
That said, Destination
s are still very nice to use with the vanilla NavHosts. There are extension functions on NavGraphBuilder
that will let you register those destinations in a type-safe way and with much less boilerplate.
Here's an example:
NavHost( // Replace with AnimatedNavHost if you're using `animations-core`
navController = navController,
startDestination = GreetingScreenDestination.route,
) {
// Replace with `animatedComposable` if you're using `animations-core`
composable(SomeScreenDestination) { // this: NavGraphBuilderDestinationScope<SomeScreenDestination.NavArgs>
SomeScreen(
arg1 = navArgs.arg1,
arg2 = navArgs.arg2,
navigator = destinationsNavigator(navController),
resultRecipient = resultRecipient(),
resultBackNavigator = resultBackNavigator(navController)
)
}
// Use `dialogComposable` if the destination has a `style = DestinationStyle.Dialog::class` or subclass
// Use `bottomSheetComposable` if the destination has a `style = DestinationStyle.BottomSheet::class`
}
If you do this, you should disable the NavGraph
s generation. Check here out to do that.