Navigation Component — What It Is, NavHost and Navigation Graph

Author: IT Sectr Published: 2026-02-22 Reading time: 7 min

Navigation Component is an Android Jetpack library for implementing navigation between app screens. The component centralizes management of the fragment stack, deep links, and argument passing. It has been part of Jetpack since 2018 and is recommended by Google for all new projects. Learn more in the official Google guide.

Key Takeaways

  • Navigation Component — a Jetpack library for centralized navigation between Android screens
  • NavGraph — an XML resource describing all screens and connections between them
  • NavHostFragment — a container in the Activity layout displaying the current navigation screen
  • NavController — the navigation control object: navigate, popBackStack, navigateUp
  • Safe Args — a Gradle plugin for type-safe argument passing between screens

What is Navigation Component?

Navigation Component is an Android Jetpack library (androidx.navigation) that provides a unified API for navigation. It includes three key elements: Navigation Graph (navigation graph), NavHostFragment (screen container), and NavController (transition controller). The component automatically manages the back stack and supports deep links.

Before Navigation Component, developers managed fragments manually through FragmentManager. This led to fragmented (literally) code: each screen had its own navigation rules, back stack states varied, and deep links required separate implementation. Navigation Component unified these scenarios. According to Google (2026), the library is installed in 90% of new Android projects.

Navigation Component integrates with other Jetpack libraries: LiveData, ViewModel, Material Design. It supports both XML fragments and Jetpack Compose via the navigation-compose extension. Stable release — 2.8.x (2025), minimum Android version — API 14.

NavGraph is an XML resource (res/navigation/nav_graph.xml) that defines all app screens and connections between them. Each screen is a destination, which can be a Fragment, Activity, or Composable. Connections between destinations are actions that define the transition direction.

xml

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    app:startDestination="@+id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name=".HomeFragment"
        android:label="Home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_home_to_detail"
            app:destination="@+id/detailFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name=".DetailFragment"
        android:label="Details"
        tools:layout="@layout/fragment_detail">
        <argument android:name="itemId"
            app:argType="integer"
            android:defaultValue="0" />
    </fragment>
</navigation>

The startDestination attribute sets the first screen displayed on launch. An action defines the target destination and optional animations. Arguments describe parameters passed to the screen — type and default value.

NavHostFragment is a container placed in the Activity layout that displays the current navigation screen. NavHostFragment automatically switches fragments when NavController.navigate() is called. NavController is the object that manages navigation: transitions, back navigation, and current route checking.

kotlin
// Layout Activity: activity_main.xml
// <androidx.fragment.app.FragmentContainerView
//     android:id="@+id/nav_host_fragment"
//     android:name="androidx.navigation.fragment.NavHostFragment"
//     app:navGraph="@navigation/nav_graph"
//     app:defaultNavHost="true" />

class MainActivity : AppCompatActivity() {

    private val navController by lazy {
        (findViewById<NavHostFragment>(R.id.nav_host_fragment))
            .navController
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // NavigationUI connects NavController to AppBar
        setupActionBarWithNavController(navController)
    }

    // Navigate to details screen
    fun openDetail(itemId: Long) {
        val bundle = Bundle().apply {
            putLong("itemId", itemId)
        }
        navController.navigate(R.id.action_home_to_detail, bundle)
    }

    override fun onSupportNavigateUp() = 
        navController.navigateUp() || super.onSupportNavigateUp()
}

app:defaultNavHost="true" is an important attribute: it intercepts the system Back button and passes control to NavController. NavigationUI is a utility for linking NavController with AppBar, BottomNavigationView, NavigationDrawer. setupActionBarWithNavController enables the Up arrow on nested screens.

Navigation Component supports custom transition animations, set in actions or programmatically. Animations are defined by four attributes: enterAnim (new screen appearance), exitAnim (current screen disappearance), popEnterAnim (appearance on back navigation), and popExitAnim (disappearance on back navigation).

xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0%"
        android:duration="300" />
</set>

// Programmatic transition with animation
val navOptions = NavOptions.Builder()
    .setEnterAnim(R.anim.slide_in_right)
    .setExitAnim(R.anim.slide_out_left)
    .setPopEnterAnim(R.anim.slide_in_left)
    .setPopExitAnim(R.anim.slide_out_right)
    .build()

navController.navigate(R.id.detailFragment, args, navOptions)

Animations work with Fragment at the FragmentTransaction level. For Jetpack Compose, animations are set via NavOptionsCompat using Compose Animation. Navigation Component does not impose restrictions on animation type — translate, scale, alpha and their combinations are supported.

Safe Args: Type-Safe Arguments

Safe Args is a Gradle plugin for type-safe data transfer between screens. The plugin analyzes NavGraph, generates Directions and Args classes with specific field types. Type matching is checked at compile time — a MissingArgumentException is caught before the app runs.

kotlin
// build.gradle (module)
plugins {
    id 'androidx.navigation.safeargs.kotlin'
}

// Safe Args generates: DetailFragmentArgs, HomeFragmentDirections
// Usage in HomeFragment:
val action = HomeFragmentDirections
    .actionHomeToDetail(itemId = 42L)
findNavController().navigate(action)

// Usage in DetailFragment:
private val args: DetailFragmentArgs by navArgs()
// args.itemId is of type Long, null cannot be passed

override fun onViewCreated(...) {
    super.onViewCreated(...)
    loadItem(args.itemId)
}

navArgs() is a Kotlin delegate for retrieving arguments in a Fragment or Activity. The plugin supports primitives, strings, Parcelable, Serializable, Enum, and arrays. For complex objects, pass an ID and load from ViewModel or database.

Deep Link is an external link that opens a specific app screen. Navigation Component handles deep links via the app:deepLink attribute in NavGraph. The system creates a PendingIntent that restores the navigation stack to the target screen, or creates a new stack if the app is not running.

xml

<fragment android:id="@+id/profileFragment"
    android:name=".ProfileFragment">
    <deepLink
        app:uri="https://example.com/profile/{userId}" />
    <argument
        android:name="userId"
        app:argType="string" />
</fragment>

// Programmatic Deep Link creation
val pendingIntent = NavDeepLinkBuilder(context)
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.profileFragment)
    .setArguments(Bundle().apply {
        putString("userId", "user_123")
    })
    .createPendingIntent()

Deep Links support URI patterns with paths and query parameters, intent action, and mime type. Placeholders ({userId}) are automatically mapped to destination arguments. Navigation Component also handles implicit deep links through AndroidManifest — just add an intent-filter to the Activity with NavHostFragment.

Navigation Compose (androidx.navigation:navigation-compose) is an extension of Navigation Component for Jetpack Compose. The API preserves the NavController and NavHost concept, but screens are Composable functions instead of Fragments. NavHost accepts a composable lambda for each route.

kotlin
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {
                val navController = rememberNavController()
                NavHost(
                    navController = navController,
                    startDestination = "home"
                ) {
                    composable("home") {
                        HomeScreen(
                            onItemClick = { id ->
                                navController.navigate("detail/$id")
                            }
                        )
                    }
                    composable(
                        route = "detail/{itemId}",
                        arguments = listOf(
                            navArgument("itemId") {
                                type = NavType.LongType
                            }
                        )
                    ) { backStackEntry ->
                        val itemId = backStackEntry
                            .arguments?.getLong("itemId") ?: 0L
                        DetailScreen(itemId = itemId)
                    }
                }
            }
        }
    }
}

Navigation Compose uses string routes instead of ids. Parameters are passed via route templates ("detail/{itemId}") and extracted from backStackEntry. rememberNavController() preserves NavController across recompositions. For Type Safety in Compose, the navigation-compose-type-safety module (experimental) is recommended.

Frequently Asked Questions

What is NavHost in Navigation Component?

NavHost is a container for displaying navigation screens. It is implemented via NavHostFragment in the XML layout. NavHost tracks the current screen in NavGraph and manages transitions. Each Activity contains one NavHostFragment.

How is Safe Args better than Bundle?

Safe Args is a Gradle plugin that generates type-safe argument classes. Bundle requires manual specification of keys and types, leading to runtime errors. Safe Args checks types at compile time and serializes data automatically.

How to pass complex objects through Navigation Component?

Complex objects are passed through ViewModel (shared across screens) or via a database by passing an ID. Safe Args only supports primitives, strings, and Parcelable. Google recommends avoiding passing large objects through navigation arguments.

How does Deep Link work in Navigation Component?

A Deep Link is configured in NavGraph via the app:deepLink attribute. Navigation Component automatically handles incoming links, creates a PendingIntent through NavDeepLinkBuilder, and restores the navigation stack to the target screen. Supports URI, intent action, and mime type.

Can I use Navigation Component with Jetpack Compose?

Yes. Navigation Compose (androidx.navigation:navigation-compose) provides NavHost for Compose. The API is similar to the XML version, but screens are Composable functions. NavController is used the same way in both versions. Google recommends Navigation Compose for new Compose projects.

Summary

  • Navigation Component — an Android Jetpack library for centralized navigation with NavController, NavHost, and NavGraph
  • NavGraph — an XML graph describing all screens (destinations) and connections (actions) between them
  • NavHostFragment — a container in the Activity layout supporting the defaultNavHost attribute for the Back button
  • Safe Args — a Gradle plugin for type-safe argument passing with compile-time type checking
  • Deep Links support URI, intent action, and mime type with automatic navigation stack restoration
  • Navigation Compose — an extension for Jetpack Compose with string routes and composable screens
  • Navigation Component is the only Google-recommended navigation approach for new Android projects

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also