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


    API Engineer

    American Express
    New York, USA
    • Full Time
    apply now

    (Senior) Android Developer – Machine Learning (w/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

    Android App Developer

    sipgate GmbH
    Düsseldorf, Remote
    • Full Time
    apply now
Load more listings

OUR VIDEO RECOMMENDATION

, ,

The Evolution of Android Graphics in Android 12/13

Android 12 and 13 both added significant new capabilities to Android platform graphics, including RenderEffect, RuntimeShader, and more. At the same time, RenderScript has been deprecated and we’ve introduced the RenderScript Intrinsics Replacement Toolkit. This…
Watch Video

The Evolution of Android Graphics in Android 12/13

Daniel Galpin
Android Developer Advocate and Fast Talking YouTuber
Google

The Evolution of Android Graphics in Android 12/13

Daniel Galpin
Android Developer Ad ...
Google

The Evolution of Android Graphics in Android 12/13

Daniel Galpin
Android Developer Advocat ...
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

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE
blog
Yes! You heard it right. We’ll try to understand the complete OTP (one time…
READ MORE

Leave a Reply

Your email address will not be published.

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

Menu