A Beginner’s Guide for Using Safe-Args in Navigation Component
A Better Approach to Send Data Between Fragments
In this post, we will be learning how to use the Safe-Args feature which has been included in the Android Jetpack’s Navigation Component. This post is an extension to my previous post Getting Started with the Navigation Component, even if you haven’t checked my previous post you can continue reading but if you are unfamiliar with the Navigation Component then you should definitely check it out.
Things to remember before passing data between destinations
Before jumping straight into how we are going to use Safe-Args in the Navigation component, we should remember that in general, we should strongly prefer passing only the minimal amount of data between destinations. For example, we should pass a key to retrieve an object rather than passing the object itself, as the total space for all saved states is limited on Android.
If we need to pass large amounts of data, we should consider using a ViewModel as described in Share data between fragments.
Project Structure
I have three fragments named MainFragment
, ViewBalanceFragment
and ViewTransactionsFragment
in this project. MainFragment
will be the one that user sees when the app launches and we will navigate to ViewBalanceFragment
from MainFragment
and pass arguments.
Adding arguments
Now, let’s add our arguments. These are the steps provided in the documentation for defining the destination arguments.
Put simply, it means we must go to our nav_graph
resource and add arguments (better to use the design mode)
For adding arguments, we must select our fragment which is going to be the destination, and after we have selected it, we can see in the attributes section there shows an attribute named Arguments and as you can see in the picture below we can easily add arguments using the add button.
When we click the add button, a dialog like this appears
Now we should fill the required fields and press Add.
Here I have filled my fields like this and notice that I am not providing a default value which is because I need to show you guys what happens when we don’t provide a default value.
After we have added the arguments from the design mode, the corresponding code is automatically generated for us by Android Studio. We can check it by switching to the text mode.
Now for enabling the Safe-Args feature provided by the Navigation Component we should add this dependency. You can get the dependency here.
Also, we must add one of these two plugins
After adding these to our Gradle files, we should rebuild our project. After the project has finished building Safe-Args will auto-generate some classes which we shall use.
Safe-Args generates classes by suffixing Directions
and Args
in fragment names. Directions
suffix is added to the fragment from which we are going to navigate and Args
suffix is added to the destination fragment which will be receiving arguments.
Here is a detailed explanation in the documentation.
With the Directions
class, we also have action
generated according to the actions defined in the nav_graph
.
Now, let’s look at how we should use all these cool stuff. :)
Passing data to another fragment using Safe-Args
Firstly, we must get our action which will help us to navigate from MainFragment
to ViewBalanceFragment
. So we should use Directions
class which the Safe-Args has auto-generated for us. Here our source fragment is MainFragment
so our Directions
class should be MainFragmentDirections
.
As you can see in the above picture, Android Studio is already suggesting us MainFragmentDirections
.
Now we need an action that would help us navigate from MainFragment
to ViewBalanceFragment
. Actions are generated according to the connections which we have made in the nav_graph.
They are generated as methods of our Directions
classes. So let's try to find the appropriate action like this.
After choosing the one that has the destination ViewBalanceFragment
we can see that the function is taking one argument, which is userID
.
If you recall, I hadn’t defined a default value earlier in this post when we were adding argument for ViewBalanceFragment
. So now if you forgot to pass argument when trying to navigate to ViewBalanceFragment
there would be a compilation error. This way Safe-Args prevents crashes that may occur in our app.
After passing the argument we should use our action in this way.
Here we can see NavController
is used for navigating using the action we have defined.
In Short,
Safe-Args lets us safely pass data to another fragment just like how we pass data to any function or constructor.
Receiving data in the destination fragment
Now that we have passed our data we should also receive our data at the other end. For that, we must go to the onViewCreated()
method of the fragment.
We can see that a new class has been generated with the suffix Args
for the same fragment. We can easily retrieve data using the fromBundle()
method.
Now for receiving data we must pass getArguments()
as our parameter.
Since Android Studio is showing an error due to type mismatch, we can wrap it using the ?.let{...}
call of Kotlin. This way we are avoiding nullable type to be passed inside the fromBundle()
method.
Then lastly we can simply receive our data by accessing the fields of the ViewBalanceFragmentArgs
class. Pretty simple, right?
References:
Android Developer Documentation
Safe Args(passing data) Navigation Component