androidkotlinnavigationandroid-jetpack-composeserializable

How to pass a list of serializable objects in Jetpack Navigation?


I have a class called Post:

data class Post(
    val id: Long,
    val type: PostType,
    val latitude: Double,
    val longitude: Double,
    val address: String,
) : Serializable

I want to pass a list of these objects from one fragment to another using Jetpack Navigation, so I tried to add an argument to my navigation graph like this:

<fragment
    android:id="@+id/destination_posts"
    android:name="com.myapp.android.ui.main.posts.PostsFragment"
    tools:layout="@layout/fragment_posts">
    <argument
        android:name="postsArg"
        app:argType="com.myapp.android.core.entity.Post[]" />
</fragment>

I tried to do it this way in the first fragment:

val action = PostsFragmentDirections.actionOpenPostsDetails(posts.toTypedArray())
navController.navigate(action)

And trying to receive it in the second fragment:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    arguments.let {
        val postsFromArgs = PostsFragmentArgs.fromBundle(it).postsArg
    }
}

But it throws an exception:

Type mismatch: inferred type is Array<Post> but Array<(out) Parcelable!>? was expected

I don't understand why it doesn't work, because as I see in documentation this type should be supported(https://developer.android.com/guide/navigation/navigation-pass-data#supported_argument_types)


Solution

  • So I made it by wrapping up my list of objects into another serializable data class that looks like that:

    data class Posts(
        val posts: List<Post>
    ) : Serializable
    

    And navigated to another fragment this way:

    val action = PostsFragmentDirections.actionOpenPostsCluster(Posts(posts))
    navController.navigate(action)
    

    Navigation documentation says that passing complex data structures over arguments is considered an anti-pattern(you can find it in the comment above by Phil Dukhov), therefore I think I can't recommend it