Master Android Navigation: Nested Graphs and Include Tags for Modular Apps
This tutorial walks through creating nested navigation graphs, extracting them into separate XML files with the include tag, and reorganizing the app into core and feature modules, enabling a modular Android project while preserving existing navigation behavior.
Overview
This article is the third installment of a series on Android's Navigation component, focusing on how to use nested navigation graphs and the <include> tag to modularize an app’s navigation flow.
Creating a Nested Graph
First, the coffeeList and coffeeEntryDialogFragment destinations are moved into a new nested graph using Android Studio’s Move to Nested Graph action. The resulting navigation XML now contains a <navigation> element with its own android:id and app:startDestination:
<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/donutList">
...
<navigation android:id="@+id/coffeeGraph" app:startDestination="@id/coffeeList">
<fragment android:id="@+id/coffeeList"
android:name="com.android.samples.donuttracker.coffee.CoffeeList"
android:label="@string/coffee_list">
<action android:id="@+id/action_coffeeList_to_coffeeEntryDialogFragment"
app:destination="@id/coffeeEntryDialogFragment" />
</fragment>
<dialog android:id="@+id/coffeeEntryDialogFragment"
android:name="com.android.samples.donuttracker.coffee.CoffeeEntryDialogFragment"
android:label="CoffeeEntryDialogFragment">
<argument android:name="itemId" android:defaultValue="-1L" app:argType="long" />
</dialog>
</navigation>
</navigation>The nested graph must have an android:id; navigation to it uses this ID, not the IDs of its child destinations.
Extracting the Graph with <include>
The nested graph can be moved to a separate file, e.g., coffee_graph.xml, containing the same <navigation> block shown above. Then the original navigation file includes it:
<include app:graph="@navigation/coffee_graph" />This approach mirrors the behavior of nested graphs while allowing the graph to reside in another module or library.
Updating the Menu
Since the included graph does not expose its child destinations, the menu item must point to the graph’s ID:
<item android:id="@id/coffeeGraph"
android:icon="@drawable/coffee_cup"
android:title="@string/coffee_name" />Running the app after these changes shows identical functionality, confirming that the navigation flow remains intact.
Modularizing the Project
Two new Gradle modules are created:
core : contains shared classes such as Donut, Coffee, DAO, and database resources.
coffee : holds all fragments, view models, adapters, layouts, and the extracted coffee_graph navigation file.
Dependencies are added accordingly:
dependencies {
implementation project(":core")
// ...
} dependencies {
implementation project(":coffee")
implementation project(":core")
// ...
}The main app module now depends on both :coffee and :core, but the navigation graph itself does not change.
Result
After refactoring, the coffee‑record feature is isolated in its own module and can be reused independently of the donut‑tracker app. All navigation actions continue to work as before, demonstrating a clean, modular architecture.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
