Navigation Between Screens
Navigation Between Screens
Every non-trivial Android app has more than one screen. Android gives you two complementary tools for moving between them: the classic Intent API — available since Android 1.0 — and the Navigation Component, a Jetpack library that imposes a predictable, graph-based structure over fragment and activity transitions. You need to understand both: Intents are unavoidable (they handle inter-app navigation and system actions), and the Navigation Component is now the standard for in-app navigation.
Intents: the Foundation of Android Navigation
An Intent is a message object that describes an action you want performed. When you pass it to startActivity(), the Android system finds an appropriate component to handle it and starts it for you.
There are two kinds of intent:
- Explicit intent — you name the exact target
Activityclass. Used for in-app navigation. - Implicit intent — you declare an action (e.g.
Intent.ACTION_VIEW) and let the system find an app that can handle it. Used to open a URL in a browser, share content, dial a number, and so on.
Explicit Intents: Moving to Another Activity
The minimal pattern to open DetailActivity from MainActivity is straightforward:
The first argument to the Intent constructor is a Context — here this refers to the current Activity, which is a Context. The second is the class object of the destination Activity.
startActivity() pushes the new activity onto the back stack. When the user presses the system Back button (or calls finish()), the top activity is popped and the previous one resumes. This stack is managed automatically; you rarely need to manipulate it directly.
Passing Data with Extras
Intents carry a Bundle of key/value pairs called extras. Use them to send primitive data to the destination activity:
public static final String fields on the destination Activity class — for example DetailActivity.EXTRA_ITEM_ID. Both sender and receiver then reference the same constant, eliminating typo bugs.
Implicit Intents: Leaving Your App
To open a web page you do not write a browser — you fire an implicit intent and the system routes it to the installed browser:
Before calling startActivity() on an implicit intent you should verify that some app can handle it, otherwise you get an ActivityNotFoundException crash:
Getting a Result Back: ActivityResult API
Sometimes you open a second activity and need a result back — for example a photo picker or a settings screen. The modern way (replacing the deprecated startActivityForResult) uses ActivityResultLauncher:
In PickerActivity, call setResult() before finish():
startActivityForResult(). It is deprecated in API 29+ and removed conceptually in newer Jetpack. Always register an ActivityResultLauncher in onCreate() — registering it later (after onStart()) throws an IllegalStateException.
The Navigation Component
When your app has many screens, managing a web of explicit intents and back-stack flags becomes error-prone. The Jetpack Navigation Component addresses this by representing your app's navigation as a declarative navigation graph — an XML file that lists destinations (Fragments) and the actions (edges) connecting them.
Add the dependency to build.gradle (app):
Creating a Navigation Graph
Right-click res → New → Android Resource File, choose type Navigation, and name it nav_graph.xml. In the XML editor you declare destinations and the actions between them:
Hosting the Graph: NavHostFragment
Your main activity layout needs a NavHostFragment — the container that swaps fragments in and out as navigation happens:
app:defaultNavHost="true" intercepts the system Back button, so the Navigation Component handles back-stack popping automatically.
Navigating with NavController
Inside any Fragment hosted by the graph, obtain the NavController and call navigate() with an action ID:
In DetailFragment, retrieve the argument from getArguments():
ListFragmentDirections.actionListToDetail(101)). This eliminates stringly-typed bundle keys and gives you compile-time errors for wrong argument types. Enable it by adding the plugin to your project-level build.gradle and applying it in the app module.
Intent vs Navigation Component: When to Use Each
- Use Intents for: starting another app (browser, camera, phone), deep links from notifications, and moving between top-level Activities (e.g. onboarding → main app).
- Use Navigation Component for: all in-app screen-to-screen navigation within a single Activity that hosts multiple Fragments. It handles the back stack, animated transitions, and deep-link URLs in one place.
Summary
Intents are Android's messaging system — explicit intents name a class, implicit intents name an action and let the system route them. The ActivityResultLauncher API is the current way to receive data back from a screen. The Jetpack Navigation Component replaces a tangle of intent calls with a single navigation graph: declare your destinations in XML, host them in a NavHostFragment, and navigate by calling NavController.navigate() with an action ID. Together these two mechanisms cover every navigation scenario you will encounter in a real Android application.