Blog Infos
Author
Published
Topics
,
Published

Navigation refers to the interactions that allow users to navigate across, into, and back out from the different pieces of content within your app. The Navigation library also provides a specific artifact to enable consistent and idiomatic navigation within screens built with Jetpack Compose.

When using navigation with jetpack compose, we define a nav host using the NavHost composable, which provides a lambda function in which we can add a destination to the NavGraphBuilder.

Suppose that we wish to navigate between ScreenA and ScreenB It’ll look like

NavHost(navController = navController, startDestination = "ScreenA") {
 composable("screen-a") { ScreenA(/*…*/) }
 composable("screen-b") { ScreenB(/*…*/) }
}
By default, all arguments are parsed as strings

As the documentation said, navigation compose also supports passing arguments between composable destinations and by default, all arguments are parsed as strings.

NavHost(startDestination = "screen-a") {
  /*…*/
composable("screen-b/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })) {
ScreenB(/*…*/)
}
}

You should extract the NavArguments from the NavBackStackEntry that is available in the lambda of the composable() function.

composable("screen-b/{id}") { backStackEntry ->
ScreenB(id = backStackEntry.arguments?.getString("id"))
}

To pass the argument to the destination, you need to add the value to the route in place of the placeholder in the call to navigate:

navController.navigate("screen-b/1")
Creating a custom data type

The above way works in most cases. You just have to pass the id and then fetch the additional information from the database. But sometimes you just want to pass your data to another screen without doing an additional request.

Jetpack navigation component allow us to create custom NavType.

NavType denotes the type that can be used in a NavArgument

Suppose that we want to pass a custom Post data type to ScreenB

data class Post(val id: Int,val title: String,val content: String)

We can create a “Post NavType”, Post must first be parcelable.

@Parcelize
data class Post(val id: Int,val title: String,val content: String) : Parcelable

Then we can create PostType class

class PostType : NavType<Post>(isNullableAllowed = false) {
override fun get(bundle: Bundle, key: String): Post? {
  return bundle.getParcelable(key)
  }
override fun parseValue(value: String): Post {
  return Gson().fromJson(value, Post::class.java)
}
override fun put(bundle: Bundle, key: String, value: Post) {
bundle.putParcelable(key, value)
}
}

The PostType extend from NavType which has the Post data class as type parameter, I also use Gson in order to deserialize the Post from argument which w’ll be a json, but you can use the convertor that you prefer.

Retrieve data

we must update the NavGraph in order to be able to retrieve the post

NavHost(startDestination = "screen-a") {
 /*…*/
 composable("screen-b/{post}", arguments = listOf(navArgument("post") { type = PostType() })) {
  val post = it.arguments?.getParcelable<Post>("post")
  ScreenB(post)
 }
}
Navigate

Now the question is about how to pass the post as parameter. First we must serialize and then encode it to uri.

/*…*/
onclick = {
val post = Post(1, "My post", "this is my wonderfull post content")
val json = Uri.encode(Gson().toJson(post))
navController.navigate("screen-b/$json")
}
/*…*/

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

This works well, but we can create a function in which we can encapsulate the serialization line, in my case a overloaded the toString() method.

override fun toString(): String {
return Uri.encode(Gson().toJson(this))
}

Now we can just use string interpolation

/*…*/
onclick = {
val post = Post(1, "My post", "this is my wonderfull post content")
navController.navigate("screen-b/$post")
}
/*…*/
Conclusion

Despite the fact that the Jetpack Compose team doesn’t recommend passing Parcelable in the navigation composable routes, you may sometimes still need to pass a custom data type as parameter and I hope this blog post can help you…

References

https://developer.android.com/jetpack/compose/navigation#getting-started

https://developer.android.com/reference/kotlin/androidx/navigation/NavType#summary

This article was originally published on proandroiddev.com on April 07, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
In the world of Jetpack Compose, where designing reusable and customizable UI components is…
READ MORE
blog

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu