[MUSIC PLAYING]
LYLA FUJIWARA: Navigating around an app, by which I
mean moving from one screen to another,
is an absolutely fundamental part of Android development.
Historically you'd do this using intents or fragment
transactions, which in simple cases, like clicking a button,
was easy enough.
But what if you wanted to do something just slightly more
complex?
For example, hooking up a common pattern like bottom navigation.
You'd need to make sure that not only your Bottom Navigation
view actually navigates but also that it
highlights the correct button.
Oh, and also that it handles the backstack in a uniform way
so that users don't end up getting lost or confused.
Cases like this are where the new navigation component
shines.
The navigation component is a collection
of libraries, a plug-in, and tooling
that simplifies Android navigation.
Beyond making the setup for common patterns like Bottom
Navigation easier, the component handles the backstack,
fragment transactions, argument passing,
navigation-based animations, and deep linking.
Importantly, it gathers up all of this navigation information
and puts it in one visualized location of your app,
the Navigation graph.
The navigation component works out
of the box with fragments and activities.
You can also extend the library to work with other screen
implementations, like your custom views.
Let's look at some examples of the navigation components
in action, with a single activity swapping out
multiple fragments.
If you're wondering why you might consider
a single-activity model, check out Ian Link's excellent talk,
which I've linked in the notes.
OK.
So one way to think about the navigation component
is that there are three major parts working together
in harmony.
These are the Navigation graph, the NavHostFragment,
and the NavController.
The Navigation graph is a new resource type.
It's an XML file that contains and centralizes information
related to navigation.
Now this information can be visualized
in the new Navigation editor that is available in Android
Studio 3.3.
It's a graphical editor to create this,
well, Navigation graph.
Each of these screens are called destinations,
or places that you can navigate to.
In this example, they're all fragments.
Now these arrows here are called actions
and they represent the different paths
that a user could take through your app.
If you click on one of the actions,
you can see a whole bunch of embedded information,
including data passed between destinations,
transition animations, backstack manipulation, and so on.
Clicking on a destination, you can see things like deep link
URLs and launch options.
This is all part of the XML of the graph.
OK, so next, we have the NavHostFragment.
This is a fragment widget that you'll add to your layout,
assuming that you're doing fragment navigation.
It's basically a window that swaps in and out
different fragment destinations that are included
in your Navigation graph.
The final piece of the puzzle is the NavController.
Each NavHostFragment has a NavController
that you'll use in your Kotlin or Java code.
And this is what actually instructs the navigation
to occur.
So if I write some code like this,
the NavController will then perform this navigation action
based off of all of that information that
was in the Navigation graph, and it will ultimately
swap out which fragment is shown in the NavHost fragment.
Now here I'm using the action's XML ID
to specify which of those action arrows to follow,
but an even better way to do this is using the navigation
component's SafeArgs plug-in.
The SafeArgs plug-in generates code
to allow you to use type-safe navigation
and argument passing.
First, you'll add the Gradle plug-in to your code.
This will generate classes based off of your Navigation graph.
It'll make these Direction classes
for any destination that has actions
and it will make Args classes for any destination
with arguments.
If you take your original navigation statement,
you can swap in these generated classes
and you'll get something that looks like this.
Instead of referring to an action by its XML ID,
you're making sure that you have an action that's
actually associated with your destination.
You can also set arguments of the action.
Pass in the wrong type and the code won't compile.
Getting the arguments you passed through is easy.
Simply use the GeneratedArgs class
and you have type-safe access to only
the correctly-named arguments.
No need to worry about the key value pairs of yesteryear.
So that was simple navigation.
Let's talk about setting up that bottom nav.
The navigation component includes
an additional navigation UI library in Java and KTX
extensions for Kotlin, that have support
for options menus, bottom navigation, navigation
view, and navigation drawer.
It also works with action bar, toolbar,
and collapsing toolbar.
For our bottom nav, you'd cut the bottom nav
to your XML as normal.
You'd also create an XML menu with IDs
that match the XML IDs of your destinations
and your Navigation graph that you want the bottom navigation
to go to.
Then you'd use navigation UI to wire up the rest.
In Kotlin, that's done with this handy extension function.
This one line of code has NavController
handle the actual navigation, making
sure to follow material design best practices as far
as backstack management goes.
On top of that, it handles highlighting
the correct bottom buttons.
Now we have only explored a few parts
of the navigation component.
For a deeper trek into navigation,
check out the code lab and the documentation,
all linked below.
Happy coding and happy navigating.