本文介绍了如何在jetpack compose中的导航中传递对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文档 中,我可以传递字符串、整数等.但是怎么做我在导航时传递对象?

From the documentation, I can pass string, integer etc. But how can I pass objects on navigation?

注意:如果我将参数类型设置为parcelable,则应用程序会因java.lang.UnsupportedOperationException: Parcelables 不支持默认值而崩溃..

Note: If I set the argument type parcelable then the app crashes with java.lang.UnsupportedOperationException: Parcelables don't support default values..

composable(
    "vendor/details/{vendor}",
        arguments = listOf(navArgument("vendor") {
            type = NavType.ParcelableType(Vendor::class.java)
        })
) {
// ...
}

推荐答案

以下基于navigation-compose版本2.4.0-alpha05的解决方案.

The following workarounds based on navigation-compose version 2.4.0-alpha05.

我找到了两种传递对象的解决方法.

I found 2 workarounds for passing objects.

1.将对象转换为 JSON 字符串:

这里我们可以使用对象的 JSON 字符串表示来传递对象.

Here we can pass the objects using the JSON string representation of the object.

示例代码:

val ROUTE_USER_DETAILS = "user-details/user={user}"


// Pass data (I am using Moshi here)
val user = User(id = 1, name = "John Doe") // User is a data class.

val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter(User::class.java).lenient()
val userJson = jsonAdapter.toJson(user)

navController.navigate(
    ROUTE_USER_DETAILS.replace("{user}", userJson)
)


// Receive Data
NavHost {
    composable(ROUTE_USER_DETAILS) { backStackEntry ->
        val userJson =  backStackEntry.arguments?.getString("user")
        val moshi = Moshi.Builder().build()
        val jsonAdapter = moshi.adapter(User::class.java).lenient()
        val userObject = jsonAdapter.fromJson(userJson)

        UserDetailsView(userObject) // Here UserDetailsView is a composable.
    }
}


// Composable function/view
@Composable
fun UserDetailsView(
    user: User
){
    // ...
}

2.使用 NavBackStackEntry 传递对象:

2. Passing the object using NavBackStackEntry:

这里我们可以使用 navController.currentBackStackEntry 传递数据,使用 navController.previousBackStackEntry 接收数据.

Here we can pass data using navController.currentBackStackEntry and receive data using navController.previousBackStackEntry.

示例代码:

val ROUTE_USER_DETAILS = "user-details/{user}"


// Pass data
val user = User(id = 1, name = "John Doe") // User is a parcelable data class.

navController.currentBackStackEntry?.arguments?.putParcelable("user", user)
navController.navigate(ROUTE_USER_DETAILS)


// Receive data
NavHost {
    composable(ROUTE_USER_DETAILS) { backStackEntry ->
        val userObject = navController.previousBackStackEntry?.arguments?.getParcelable<User>("user")

        UserDetailsView(userObject) // Here UserDetailsView is a composable.
    }
}


// Composable function/view
@Composable
fun UserDetailsView(
    user: User
){
    // ...
}

重要说明:如果我们在导航时弹出返回堆栈,则第二种解决方案将不起作用.

Important Note: The 2nd solution will not work if we pop up back stacks on navigate.

这篇关于如何在jetpack compose中的导航中传递对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 07:58