Architecture : Android Jetpack – Navigation Library (Part2

Part 2 — Actions

In this part we will learn to pass data between destinations in a type-safe way and how to define transitions for this actions.

Pass data between destinations

We can use two different ways to pass data to a destination. The old fashioned using a Bundle or the new type-safe way using the safe-args Gradle plugin. Using a Bundle isn’t the best way, it isn’t type-safe and we don’t know which arguments are required. A workaround for this problem is to create static createInstance() methods and other boilerplate code. With the safe-args Gradle plugin this boilerplate code will be generated for us. Let’s have a look.

Dependencies

First of all we have to add the following classpath to our projects build.gradle

buildscript {
repositories {
google()
}
dependencies {
classpath "
android.arch.navigation:safe-args-gradle-plugin:1.0.0-alpha01"
}
}

Please notice: i have replaced the androidx.navigation:safe-args-gradle-plugin from the documentation with android.arch.navigation:safe-args-gradle-plugin because the new androidx can’t be resolved at the moment.

And in our app or module build.gradle we have to add

apply plugin: 'androidx.navigation.safeargs'

Arguments

After that we have to define arguments for our destination.

At the moment we can only use four types of arguments inferred, int, string, reference. Someone has already opened an issue for adding more types: see here.

  1. Select the destination in the navigation graph where the argument is received.
  2. In the Attributes view click on the + next to the arguments section
  3. Now we have to choose a name
  4. We can select a type from the dropdown, default is string
  5. At least we can choose a default value.

The safeargs plugin now generates simple object and builder classes.

  • For the source of our action it will create a class with the Fragment name and the suffix Directions. In our case it will generate ListFragmentDirections. This class has a method with the name of the action detail() which receives the defined arguments.
  • For the action it generates a class with the id of the action. In our case Detail
  • For the destination fragment it will generate a class with the name of the Fragment and the suffix Args. In our case the generated class is named DetailFragmentArgs.

Code

Now we want to use the generated classes. To navigate to our DetailFragment we have to implement the following code:

val direction = ListFragmentDirections.detail()
direction.setItemId(1)
findNavController().navigate(direction)

First of all we call the action_list_to_detail() method on the generated ListFragmentDirections class. Because we have defined a default value for the argument itemId we have to set it in the next step. Unfortunately the code is generated in Java and doesn’t support default values for methods.

The last line of code is very similar to the one from Navigation Part1. We have to find the NavController and call the navigate method with our NavDirection.

To receive the argument we use the generated DetailFragmentArgs class. In our Detail Fragment we implement the following code:

val detailArgs = DetailFragmentArgs.fromBundle(arguments)
val itemId = detailArgs.itemId

Transitions

If we create an Action we can provide transitions. How to define a animation can you read here: Declare Animations in XML

We will define transitions for our Action from ListFragment to DetailFragment.

There are four properties for transitions:

  • enterAnim: the animation for the target (DetailFragment) fragment/activity when we navigate to it
  • exitAnim: the animation for the source (ListFragment) fragment/activity when we navigate away from it
  • popEnterAnim: the animation for the target(ListFragment) fragment/activity when we press back
  • popExitAnim: the animation for the source (DetailFragment) fragment/activity when we press back

Other Navigation Options

We can provide three Launch Options each of it is an equivalent to an Activity Flag:

Last but not least we can define a PopUpTo Destination. All non-matching destinations should be popped from the back stack if we set it.

Whats next?

In the third Part we will build a more complex App with BottomNavigation and Toolbar and we will learn how they work together with the Navigation Component. We will although define Deeplinks and have a look at testing.

LEAVE A REPLY

Please enter your comment!
Please enter your name here