Android JetPack Series: Navigation
Android, as a developer platform, has evolved a lot over time and we have been seeing new tools, techniques and enhancements introduced that make app development simplified be it Constraint Layout, Visual Editor, Profiler or other performance tools. Last week at the I/O event, Google launched Android Jetpack.
As the name suggests, Jetpack is a combination of tools and libraries(pack) which make development faster(jet) and simpler. It provides common infrastructure code so you can focus on what makes your app unique.When something major is launched for developers, the first obvious question for developers is the support for backward compatibility. Jetpack takes advantage of android support library to provide us backward compatibility. That being said, let’s dive into the details!
The Jetpack comprises of basic 4 categories viz. Architecture, UI, Foundation and Behaviour.
Most of the topics mentioned above have been there since a while as individual libraries or in Support Library. However, there a few new ones Navigation, Paging, WorkManager, Slices and Android KTX(* in image above) that directly paved its way in JetPack whereas other existing libraries became a part of JetPack now.
In this series we will go through the newly introduced components in JetPack, starting with Navigation.
Navigation
If you’ve seen iOS developers work, you may have seen storyboards in action already. Navigation component lets you define flow of the screens. To take advantage of navigation, we must use Navigation Architecture component.
Principles of Navigation
- There should be a fixed entry point for the app. For e.g. In most cases its the SplashScreen
- The “navigation state” of the app can be looked up on as a stack of screens in the flow
- The app should be designed such that the ‘UP’ button never exits the app
- Up and Back are equivalent within your app’s task. To know more about tasks and backstack, read here
- Navigation architecture focuses on single activity app. Deep linking in such case should create same backstack when navigating in the app to same destination
Getting Started
To make use of navigation in your project, add following in project gradle file
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0-alpha14'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath 'android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0-alpha01'
}
Now in your modules gradle add following dependency
// Navigation
implementation "android.arch.navigation:navigation-fragment:$versions.navigation"
implementation "android.arch.navigation:navigation-ui:$versions.navigation"
Next step is to create navigation
folder under res. Same hierarchy where layout
folder is placed. You can defined multiple nav_graph
or flows in this folder to define the navigation flow. Provided there is a launch point and an end destination.
Example
The following example shows navigation between StartFragment and EndFragment
placed in StartActivity
. The layout for StartActivity
looks as below:
// start_activity.xml<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</android.support.v4.widget.DrawerLayout>
The navGraph
value in activity’s layout defines the navigation flow.
// nav_graph.xml<?xml version="1.0" encoding="utf-8"?>
<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/launcher_home">
<fragment
android:id="@+id/launcher_home"
android:name="com.neha.androidp.ui.start.StartFragment"
android:label="Home"
tools:layout="@layout/start_fragment">
<action
android:id="@+id/end_action"
app:destination="@id/end_dest" />
</fragment>
<fragment
android:id="@+id/end_dest"
android:name="com.neha.androidp.EndFragment"
android:label="End"
tools:layout="@layout/fragment_end">
</fragment>
</navigation>
The launcher home is the StartFragment
with action as end_action
which corresponds to end_dest
. In the Design view, this looks as follows.
When an action is performed on the StartFragment
, the EndFragment
is launched. In theStartFragment
, adding the below snippet will bind end_dest
to the button.
On pressing back, the StartFragment
reappears as per principles of navigation. This feature helps visualize and define flows appropriately. Another interesting thing is passing parameters between fragments is really simplified.
// nav_graph.xml<fragment
android:id="@+id/end_dest"
android:name="com.neha.androidp.EndFragment"
android:label="End"
tools:layout="@layout/fragment_end">
<argument
android:name="screenName" app:type="string" />
<argument
android:name="category" app:type="integer" />
</fragment>
In the next part of the series, we will explore Paging, WorkManager, Slices and Android KTX. Stay tuned!