Navigation (Fragment & Compose) Quiz

UI › Material & Nav

In Navigation Compose with type-safe routes, how do you read the arguments inside a destination's composable?

Answer: backStackEntry.toRoute<DetailRoute>()

toRoute<T>() deserializes the back stack entry into the @Serializable route instance, giving typed access. Raw Bundle getString is the old string-route approach, and SafeArgs is the XML/Fragment generator, not used here.

Which combination prevents a destination from being duplicated on the back stack when re-selecting the same bottom-nav tab?

Answer: Use launchSingleTop with popUpTo to the graph start

launchSingleTop reuses the existing top instance instead of pushing a new copy; combined with popUpTo to the graph start it gives the standard duplicate-free bottom-nav behavior.

What does Safe Args generate for XML-based navigation graphs?

Answer: Type-safe Directions and Args classes for checked arguments

The Safe Args Gradle plugin generates Directions (for navigating with arguments) and Args (for reading them) classes, replacing untyped Bundle keys with compile-time-checked types.

Which statement best distinguishes an implicit deep link from an explicit deep link?

Answer: Implicit links are URI matches via intent-filter; explicit ones jump right to a destination

Implicit deep links are URI matches declared via intent-filter/navDeepLink so external sources open the app at a destination, while explicit deep links (e.g. NavDeepLinkBuilder/PendingIntent) navigate in-app directly, typically from notifications.

How should a ViewModel be scoped so two sibling destinations in the same flow can share it?

Answer: Scope it to the navigation graph, like navGraphViewModels.

Graph-scoped ViewModels live as long as the graph is on the back stack, so destinations within that graph share one instance. Application scope leaks state globally and per-destination instances cannot share data.

In Navigation Compose, what is a destination registered inside a NavHost?

Answer: A composable function registered via composable(...)

Navigation Compose destinations are composables registered with composable(route) (or composable<Route> for type-safe routes) inside the NavHost; Fragments and Activities are not the unit of navigation here.

What does popUpTo("home") { inclusive = true } do when navigating?

Answer: Removes destinations up to and including 'home' before nav.

popUpTo removes entries up to the named destination, and inclusive = true also removes 'home' itself, so the new destination effectively replaces the popped stack.

In Jetpack Compose, what is the idiomatic way to obtain the NavController that survives recomposition and is handed to a NavHost?

Answer: val navController = rememberNavController()

rememberNavController() creates and remembers a NavHostController across recompositions so the back stack is preserved. There is no built-in CompositionLocal for it, and constructing one each recomposition would discard navigation state.

What is the practical difference between NavController.navigateUp() and NavController.popBackStack()?

Answer: navigateUp() uses Up semantics and can fail at a graph root; popBackStack() always pops the top

navigateUp() encodes Up affordance behaviour and may differ at a graph's start destination (for example with synthesized deep-link back stacks), while popBackStack() simply removes the current destination from the stack.

What is required to use type-safe @Serializable routes in Navigation Compose?

Answer: Apply the Kotlin serialization plugin and annotate routes with @Serializable

Type-safe routes are encoded and decoded with kotlinx.serialization, so the org.jetbrains.kotlin.plugin.serialization plugin must be applied and each route annotated @Serializable. Safe Args is the older XML/Fragment-only generator and is unrelated here.

In a single-activity app, what is the recommended way to return a result from a destination back to the screen that launched it?

Answer: Write it to the previous entry’s SavedStateHandle and observe it in the caller

Each NavBackStackEntry exposes a SavedStateHandle; the called destination sets a value on previousBackStackEntry's SavedStateHandle and the caller observes it (as LiveData/StateFlow). Navigation arguments only flow forward, not back.

How can a ViewModel read its destination's navigation arguments without them being passed manually through the constructor?

Answer: Through the injected SavedStateHandle, pre-seeded with the arguments

A ViewModel scoped to a NavBackStackEntry receives a SavedStateHandle pre-populated with that destination's arguments, so it can read them by key (or via toRoute) with no constructor plumbing.

How do you declare a nested navigation graph in the Navigation Compose DSL?

Answer: With a nested navigation(startDestination = ...) { } block in NavHost

In Compose you group destinations into a subgraph using the navigation(...) builder with its own start destination inside the NavHost; this scopes the feature and enables graph-scoped ViewModels. Nested graphs are fully supported in Compose.

Which API lets a Compose bottom bar reactively highlight the tab matching the currently displayed destination?

Answer: navController.currentBackStackEntryAsState(), comparing its destination's route to each tab

currentBackStackEntryAsState() returns a State<NavBackStackEntry?> that recomposes on every destination change, so the bar can compare the current route to each item and mark the selected one. A one-time read never updates, and an unremembered listener re-registers on each recomposition.

Back to Navigation (Fragment & Compose)