In this article, you will learn who this Safe Args is, how it makes life easier and what is the product of its work, including behind the scenes.
You are now in the second part of a large article about Navigation Component in a multi-module project. If this is your first time hearing about Navigation Component, then I recommend that you first read what Navigation Component is . If you are already familiar with the basics, then you can move on to the most interesting:
Working with Navigation Component in a multi-module project with SafeArgs.
Multistack navigation solution
Safe Args is a separate plugin from the Navigation Component, but designed specifically to make the library easier to work with. With it, there is no need to specify the destination id and pass parameters through the Bundle - the plugin generates separate classes for this and has a set of extensions to work with them. Let's figure out how it all works.
First, along with the plugin, there is a new tag in xml: <argument>. It applies to both action and destination - this way you can send and receive parameters in a more convenient way. Secondly, based on the screens and transitions specified in the graph, special classes are generated that can be specified in the NavController instead of the id action.
Show me the code!
<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/graphuserflow”
app:startDestination=”@id/fragmentUserList”>
<fragment
android:id=”@+id/fragmentUserList”
android:label=”FragmentUserList”
android:name=”com.example.usersList.UserListFragment”
tools:layout=”@layout/fragmentuserlist”>
<action
android:id=”@+id/actiontouserdetails”
pp:destination=”@id/fragmentUserList” >
<argument
android:name=”userId”
app:argType=”integer”
app:nullable=”false” />
</action>
</fragment>
<fragment
android:id=”@+id/fragmentUserDetails”
android:label=”FragmentUserDetails”
android:name=”com.example.usersList.UserDetails”
tools:layout=”@layout/fragmentuser_details”/>
</navigation>
: , , .  —  <argument>, users details userId. , .
class UserListFragmentDirections private constructor() {
private data class ActionUserFromListToDetails(
val userId: Int
) : NavDirections {
override fun getActionId(): Int = R.id.actionToUserDetails
override fun getArguments(): Bundle {
val result = Bundle()
result.putInt(“userId”, this.userId)
return result
}
}
companion object {
fun actionToUserDetails(userId: Int): NavDirections =
ActionToUserDetails(userId)
}
}
generated- , ,  — , , . userId.
:
navController.navigate(
UserListFragmentDirections.actionToUserDetails(userId)
)
destination- extension, .
private val args by navArgs<UserDetailsFragmentArgs>()
private val userId by lazy { args.userId }
, Bundle, .
Safe Args is a nice addition to the Navigation Component, thanks to which we made it easier for ourselves to work with transition id and handling of receiving / sending their arguments. Whether to use it or not is up to you, but further narration is based on the use of this plugin. Spoiler alert: it will bring a lot of problems, but in the end everyone will be happy :)
And now to the fun part. Let's take a look at how you can organize work with the Navigation Component in a multi-module project together with SafeArgs and iOS-like multistack navigation .