We've covered the basics of using fragments. Now, let's explore how fragments can interact with each other and the activity. In previous topics, we discussed interaction through FragmentTransaction. In this topic, we'll focus on navigation. Android offers several ways to implement navigation, and here we'll use Jetpack's Navigation component.
Navigation graph
First, to use the Navigation component, you need to add it to Gradle. You must also add the AndroidX Fragment library to work with fragments. Add the following dependencies to your project's build.gradle file.
dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version"
}The Navigation graph helps you navigate between fragments and activities (also known as "destinations" in the context of navigation). It's an XML file that contains navigation information. You can use the Navigation Editor to visualize this information. A finished graph will look something like this:
The arrows represent actions, and the screens represent destinations. The actions show how to move from one point to another. To perform the actual navigation, you need to call the correct action at runtime.
You can view the XML code by selecting the Code option or see it with the visualization by selecting Split.
To use the Navigation Graph, create it through Resource Manager → Navigation. Add a new Navigation Resource File by clicking the "+" button in the top left-hand corner. You can also right-click on the res folder and select New > Android Resource File. Select Navigation as the Resource type in the dialog box.
After creating the graph, a new folder with your Navigation Graph will appear in the res folder. In the navigation file, you must add all fragments you want to connect. After creating the fragment classes, each with some text in the center and a button at the bottom, add them to the navigation graph and connect them with arrows.
To add the fragment you need, click on the New Destination icon and select the appropriate option. You can create a new fragment, select an existing one, or add a placeholder destination.
Note that each fragment must have a unique id.
The "home" icon near the fragment indicates that this will be the first fragment displayed on the screen. To choose a starting fragment, right-click on one of the fragments and select "Set as Start Destination". Using the arrows on the right side of each fragment, you can indicate the order of your fragments. The arrows define the action that will trigger the navigation to the next fragment.
Your finished navigation XML file will look something like this:
<?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"
android:id="@+id/navigation"
app:startDestination="@id/defaultFragment">
<fragment
android:id="@+id/defaultFragment"
android:name="com.example.hyperskill_navigation.FragmentDefault"
android:label="fragment_default"
tools:layout="@layout/fragment_default">
<action
android:id="@+id/action_defaultFragment_to_firstFragment"
app:destination="@id/firstFragment" />
</fragment>
<fragment
android:id="@+id/firstFragment"
android:name="com.example.hyperskill_navigation.FragmentFirst"
android:label="fragment_first"
tools:layout="@layout/fragment_first" >
<action
android:id="@+id/action_firstFragment_to_secondfragment"
app:destination="@id/secondFragment" />
</fragment>
<fragment
android:id="@+id/secondFragment"
android:name="com.example.hyperskill_navigation.FragmentSecond"
android:label="fragment_second"
tools:layout="@layout/fragment_second" >
<action
android:id="@+id/action_secondFragment_to_defaultFragment"
app:destination="@id/defaultFragment" />
</fragment>
</navigation>NavHostFragment
After creating your navigation graph, you need to add a NavHostFragment to your layout for fragment navigation. Add this to your app's main activity. The NavHostFragment acts as a window that switches between different fragment destinations in the navigation graph. To include the NavHostFragment, add a FragmentContainerView to your activity. This container will display your entire graph.
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation" />We use the android:name attribute to specify that we want to instantiate the NavHostFragment class. The app:defaultNavHost="true" line allows the NavHost to intercept system Back button presses.
Each NavHostFragment has a NavController that you'll use in your Java/Kotlin code. The NavController manages navigation between fragments. You can access the relevant NavController through the findNavController() function. Its navigate() function accepts a fragment or action ID as an argument, as shown below. Place this code in your button's OnClickListener.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.go_forward)
.setOnClickListener {
findNavController().navigate(R.id.your_fragment_id)
}
}Here's what the result with a button will look like:
Passing data between fragments
To pass data between fragments, use an arguments bundle. First, create a Bundle in the source fragment and add all the necessary objects with their corresponding keys. You'll use these keys later to retrieve the data in the target fragment.
val bundle = Bundle()
bundle.putString("Key", thing)Note that you can also create a Bundle like this:
val bundle = bundleOf("Key" to thing)Next, add your bundle as an argument to the navigate() function when transitioning to the next fragment.
findNavController().navigate(R.id.firstFragment, bundle)In the receiving fragment, you can access the arguments bundle to retrieve its contents.
val thing = arguments?.getString("Key")Conclusion
Here's a recap of what you should remember from this topic:
The Navigation graph is a convenient tool for navigating between fragments.
The Navigation Editor helps you visualize navigation information.
The
NavHostFragmentis the area where navigation takes place.The
NavHostFragment'sNavControllermanages navigation in the app.You can pass arguments between destinations using Bundle objects.