The Android Navigation component is implemented using Kotlin in a multi-step process.
Here's
a breakdown of the typical workflow, assuming you're starting with a new or existing Android
project:
1. Add Dependencies to build.gradle (Module: app)
First, you need to include the necessary Navigation component libraries in your app's
build.gradle file. You'll typically need navigation-fragment-ktx and navigation-ui-ktx. If you're
using Safe Args for type-safe argument passing, you'll also add the Safe Args plugin.
Gradle
// In your project-level build.gradle file (root project)
buildscript {
ext.nav_version = "2.7.7" // Use the latest stable version
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.X.X' // Your current Android Gradle Plugin version
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
// In your app-level build.gradle file (module: app)
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'androidx.navigation.safeargs.kotlin' // Apply Safe Args plugin
}
android {
// ...
}
dependencies {
implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
// Optional: If you need dynamic feature module support
// implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
}
2. Create a Navigation Graph XML File
This is the core of your navigation. Right-click on your res directory, then select New > Android
Resource File.
● Resource type: Navigation
● File name: nav_graph (or any descriptive name)
This will create res/navigation/nav_graph.xml. Open it, and you'll see a visual editor in Android
Studio.
3. Add Destinations to the Navigation Graph
In the nav_graph.xml editor, you can add different types of destinations:
● Fragments: Most common. Each screen in your app is typically a Fragment.
● Activities: Less common for the main navigation flow, but possible if you have a
separate flow managed by an Activity.
● Nested Graphs: For organizing complex navigation flows.
To add a Fragment destination:
1. Click the "New Destination" button (a plus sign with a circle) in the Design tab.
2. Select "Create new destination" and choose "Fragment (Blank)" or "Fragment (List)", etc.
Name your Kotlin Fragment class (e.g., HomeFragment, DetailFragment).
3. Drag and drop or select existing fragments from your project.
4. Define Actions (Connections between Destinations)
Actions represent the transitions from one destination to another.
1. In the nav_graph.xml editor, drag a connection arrow from the source destination (e.g.,
HomeFragment) to the target destination (e.g., DetailFragment). This creates an
"action."
2. Select the action in the graph. In the Attributes pane, you can configure:
○ ID: A unique ID for the action (e.g., action_homeFragment_to_detailFragment).
Safe Args will use this to generate methods.
○ Pop behavior: How the back stack is handled when navigating (e.g., popTo,
popUpToInclusive).
○ Animations: Custom entry/exit animations.
5. Set a Start Destination
Every navigation graph needs a starting point. In nav_graph.xml, select the destination you want
to be the default start screen (e.g., HomeFragment) and click the "Set Start Destination" icon (a
house icon).
6. Implement NavHostFragment in Your MainActivity Layout
Your MainActivity's layout (e.g., activity_main.xml) will host the navigation graph. You use a
NavHostFragment for this.
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
1
● android:name="androidx.navigation.fragment.NavHostFragment": Specifies the
NavHost.
● app:defaultNavHost="true": Ensures that the NavHostFragment intercepts system back
button presses.
● app:navGraph="@navigation/nav_graph": Links this NavHost to your navigation graph
XML.
7. Navigate Between Destinations in Kotlin Fragments
From within your Fragments, you'll use the NavController to trigger navigation.
Kotlin
// In your HomeFragment.kt
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.example.yourapp.R // Replace with your actual package
class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
view.findViewById<Button>(R.id.button_to_detail).setOnClickListener {
// Option 1: Using action ID directly (less type-safe)
// findNavController().navigate(R.id.action_homeFragment_to_detailFragment)
// Option 2: Using Safe Args (recommended for type-safety)
val action = HomeFragmentDirections.actionHomeFragmentToDetailFragment(
someStringArg = "Hello from Home!",
someIntArg = 123
)
findNavController().navigate(action)
}
return view
}
}
● findNavController(): A convenient extension function to get the NavController associated
with the current Fragment.
● Maps(action): Triggers the navigation.
8. Pass Arguments with Safe Args (Recommended)
If you need to pass data between destinations:
● In nav_graph.xml:
○ Select the target destination (e.g., DetailFragment).
○ In the Attributes pane, click the "Add Argument" button (+ icon under Arguments).
○ Define the argument name (e.g., someStringArg), type (e.g., string), and
optionally a default value.
● XML
<fragment
android:id="@+id/detailFragment"
android:name="com.example.yourapp.DetailFragment"
android:label="DetailFragment"
tools:layout="@layout/fragment_detail">
<argument
android:name="someStringArg"
app:argType="string" />
<argument
android:name="someIntArg"
app:argType="integer"
android:defaultValue="0" />
</fragment>
●
●
● Rebuild Project: After adding arguments in the XML, rebuild your project (Build >
Rebuild Project). This generates the Safe Args classes.
● In the sending Fragment (e.g., HomeFragment):
● Kotlin
val action = HomeFragmentDirections.actionHomeFragmentToDetailFragment(
someStringArg = "Hello from Home!",
someIntArg = 123
)
findNavController().navigate(action)
●
● Notice the generated HomeFragmentDirections class.
● In the receiving Fragment (e.g., DetailFragment):
● Kotlin
import androidx.navigation.fragment.navArgs
class DetailFragment : Fragment() {
private val args: DetailFragmentArgs by navArgs()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val receivedString = args.someStringArg
val receivedInt = args.someIntArg
// Use receivedString and receivedInt to update UI
Log.d("DetailFragment", "Received: $receivedString, $receivedInt")
}
}
●
● The navArgs() delegate provides easy access to the arguments.
9. Integrate with UI Components (Optional but Recommended)
For common UI patterns like NavigationView (Navigation Drawer) or BottomNavigationView, the
Navigation component provides setupWithNavController extension functions.
Kotlin
// In your MainActivity.kt
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.navigation.NavigationView
import com.google.android.material.bottomnavigation.BottomNavigationView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)
as NavHostFragment
val navController = navHostFragment.navController
// Example: Setup with BottomNavigationView
val bottomNavView = findViewById<BottomNavigationView>(R.id.bottom_nav_view)
bottomNavView?.setupWithNavController(navController)
// Example: Setup with NavigationView (for Navigation Drawer)
val navView = findViewById<NavigationView>(R.id.nav_view)
navView?.setupWithNavController(navController)
// Example: Setup AppBarConfiguration for Up button (ActionBar/Toolbar)
val appBarConfiguration = AppBarConfiguration(navController.graph) // For top-level
destinations
// If you have a DrawerLayout, include it:
// val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
// val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
}
// Handle Up button presses
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
This comprehensive approach leverages the Navigation component's features to build a robust,
maintainable, and user-friendly navigation system in your Kotlin Android app.