1

i am developing side-project with compose and I am interested in Compose navigation. the thing that I want is to pass Parcelable object from one Composable screen to another. so the navigation is like this :

composable(
        route = Screen.DetailsScreen.route,
        arguments = navArgument(PARAMETER_MOVIE_KEY) {
            NavType.ParcelableType(Movie::class.java)
        }
    ) {
        DetailsScreenGuide(navController, it)
    }

when navigating from Home Screen, I put parcelable object to NavController.currentBackStackEntry.

navController.currentBackStackEntry?.arguments?.putParcelable(
    "movieArgument",
    homeScreenNavGraphDataModel.movie
)
navController.navigate(route) // here, route = "movieDetails/movie"

and then, before calling the MovieDetails composable Screen, I try to get the movie object from navController.previousBackStanEntry.

val movie = remember {
    navController.previousBackStackEntry?.arguments?.getParcelable<Movie>(
        "movieArgument"
    )
}

but here, the movie variable is null and I can not receive the object. (the navigation is working and it's inflating MovieDetails composable function

can you help me with debugging these code snippets or am I mistaken somewhere?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
  • Have you look at this answer? https://stackoverflow.com/questions/65610003/pass-parcelable-argument-with-compose-navigation/65619560#65619560 – nglauber Jul 20 '21 at 14:13
  • Does this answer your question? [Pass Parcelable argument with compose navigation](https://stackoverflow.com/questions/65610003/pass-parcelable-argument-with-compose-navigation) – nglauber Jul 20 '21 at 14:14

1 Answers1

0

I had the same issue before. I used the below code and it's working for me

fun NavController.navigate(
    route: String,
    args: Bundle,
    navOptions: NavOptions? = null,
    navigatorExtras: Navigator.Extras? = null,
) {
    val linkRequest = NavDeepLinkRequest
        .Builder
        .fromUri(NavDestination.createRoute(route).toUri())
        .build()

    graph.matchDeepLink(linkRequest)?.apply {
        navigate(destination.id, args)
    } ?: navigate(route, navOptions, navigatorExtras)
}

Hint: Don't use arguments = listOf() in the destination it will cause a crash if you're passing Parcelable or Serializable data types

So the destination shoudn't be like this

composable(
  "movies/{movieDetails}",
  arguments = listOf(navArgument("movie") { type = NavType.ParcelableType(Movie::class.java) })
) {...}

It should be simply like this

composable(
  "movies/{movieDetails}"
) {...}
MohamedHarmoush
  • 1,033
  • 11
  • 17