Android Navigation
A Navigation library is a tool that handles the navigation between fragments with ease. This is achieved by attaching a navigation controller to the Activity and creating a navigation graph that handles the back-and-forth movement between fragments.
A navigation graph contains the fragment destinations for activity and all the actions that occur with respect to those destinations. Each destination is represented as a preview in the navigation graph file, and every action is represented as an arrow.
Navigation can be added to an Android Project using the below steps:
1. To the build.gradle file, add the dependencies:
dependencies {
def nav_version = "2.3.5"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
// Feature module Support
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
// Testing Navigation
androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
// Jetpack Compose Integration
implementation "androidx.navigation:navigation-compose:2.4.0-alpha06"
}
2. Add a navigation graph to your project
- Create new Android Resource File by rightclicking on the res directory and selecting new option in the project window. The New Resource File dialog appears.
- Type a name according to the requirement in the File name field, like "nav_graph".
- Select navigation from the Resource Type field option and click OK.
3. After adding the navigation graph, Android Studio opens a Navigation Editor. It allows you to visually navigate between fragments using destinations and actions. It has a destination panel, a graph editor, and an attributes pane, which together make the navigation graph customizable.
4. Add an Activity to hist the navigation. The fragment added in the activity should specify its navigation graph using the “navGraph” attribute and should set “defaultNavHost” as true
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
5. To navigate between fragments, use the following code segment in your Host Activity.
@Override
publicvoid onClick(View view){
NavDirections action =
SpecifyAmountFragmentDirections
.actionSpecifyAmountFragmentToConfirmationFragment();
Navigation.findNavController(view).navigate(action);
}
Arguments
Fragments can be passed arguments when being attached to the Activities. These arguments allowthe fragment to populate data in accordance with the project requirement, making fragments customizable and widely reusable. Fragments can be passed arguments in two ways. As bundles using the arguments property or when invoked using .navigate() function. To send arguments using navigation, another dependency needs to be added to the build.gradle file for the android project. Along with a safeargs plugin. This can be done by adding the following:
buildscript {
repositories {
google()
}
dependencies {
def nav_version ="2.3.5"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
}
}
Add this line to your app or module's build.gradle file:
apply plugin:"androidx.navigation.safeargs"
To set arguments as bundles, you can use the following code segment,
//adds arguments in dynamic fragments dynamically
Bundle bundle =newBundle();
bundle.putInt("ID", 1);
Navigation.findNavController(view).navigate(R.id.confirmationAction, bundle);
The arguments can be accessed within the Fragment using the arguments property. To extract id from the arguments, add the following code segment in the fragments class.
TextView StudentId = view.findViewById(R.id.textViewId);
tv.setText(String.valueOf(getArguments().getInt("ID")));
Communication between Activity and Fragment
We will discuss two ways of communication i.e., Activity to Fragment and the vice-versa.
Activity to Fragment
Activity to fragment communications is relatively simpler. All you need to do is create a public function in our fragment and call the function in the activity to perform the task as the activity already has an instance of the fragment. This can be done as follows:
Fragment Code:
public void receiveMsg(String msg) {
fr_textView.setText(msg);
}
Activity Code:
FragmentManager manager = getSupportFragmentManager();
NewFragment newFragment = (NewFragment) manager.findFragmentById(R.id.newfrag);
newFragment.receiveMsg("Hello Fragment Where are you ?");
Fragment to Activity
The fragment has an instance of the activity as well, and this instance can be used to access public function in the same way but if the fragment is to be used by multiple activities throughout the application, this might not be possible. In such cases, we create an interface that is implemented by the Activity and use this interface to communicate between the fragment and the activity. Every activity that uses the fragment can implement the functions as per their needs allowing customization to a great extent. This can be done as follows:
Callback Interface:
public interface SendMessages {
void sendMSG(String message);
}
You can define the method according to your need after implementing the interface.
public class NewActivity extends AppCompatActivity implements MyFragment.SendMessages {
........
// receive data from fragments
@Override
public void sendMSG(String message) {
act_textView.setText(msg);
}
}
Youmust remember to call the abstract methodof the interfacefrom the fragment and cast it into an activity. If not done correctly,it must catch a ClassCastException.