【问题标题】:Pass object through navigation通过导航传递对象
【发布时间】:2022-03-15 09:08:33
【问题描述】:

我需要将Song 对象从HomePage 传递给PlayerPage。现在我已经创建了一个可以容忍的路由机制。因为我的应用程序中有底部导航和全屏页面。

现在我面临通过导航传递对象的问题。我已经参考了thisthis 指南。但无法将答案与我现有的导航联系起来。

我创建了一个Router 接口:

interface Router {
    fun openHome()
    fun openAlbumPage()
    fun openNotification()
    fun openSettings()
    fun openPlayer()
    fun openSearchPage()

    fun goBack()
    fun <T: Any> getArgs(tag: String): T?
}

实现如下:

class RouterImpl (
    private val navHostController: NavHostController,
    private val startDestination: String = HOME
) : Router {
    override fun openHome() {
        navigate(Page.Home, removeFromHistory = true, singleTop = true)
    }
    .....
    override fun openPlayer() {
        navigate(Page.Player)
    }
    private fun navigate(
        page : Page,
        removeFromHistory : Boolean = false,
        singleTop: Boolean = false
    ){
        navHostController.apply {
            navigate(page.route){
                if(removeFromHistory){
                    if(singleTop){
                        popUpTo(Page.Home.route)
                    }else{
                        popUpTo(0){
                            saveState = false
                        }
                    }
                } else{
                    restoreState = true
                }
                launchSingleTop = singleTop
            }
        }
    }

    override fun goBack() {
        navHostController.apply {
            navigateUp()
            navigate(startDestination){
                launchSingleTop = true
                restoreState = true
            }
        }
    }

    private fun checkArgsAndNavigate(it: Any?, page: Page): () -> Unit = {
        it?.let {
            navHostController.putArgs(Pair(page.tag, it))
        }
        navigate(page)
    }

    @SuppressLint("LongLogTag")
    override fun <T: Any> getArgs(tag: String): T? {
        return try{
            navHostController.previousBackStackEntry?.arguments?.get(tag) as T?
        } catch (ex: Exception){
            Log.d("Exception from getArgs: ", ex.toString())
            null
        }
    }
}

我通常将路由器对象传递给所需的按钮,然后调用相关的方法:router.openPlayerPage

在我的NavigationContainer

fun NavigationContainer(
    router: Router,
    navController: NavHostController,
    paddingValues: PaddingValues
){
    val startDestination = remember { mutableStateOf(Page.Splash.route) }
    LaunchedEffect(startDestination){
        if(startDestination.value == Page.Home.route){
            router.openHome() 
        }
    }
    NavHost(
        navController = navController,
        startDestination = startDestination.value
    ){
        composable(Page.Splash.route){
            SplashPage(
                goBack = {
                    startDestination.value = Page.Home.route
                }
            )
        }
        /*
             Bottom Navigation Bar
        */
        composable(Page.Home.route){
            HomePage(router)
        }
        composable(Page.Favorite.route){
            FavoritePage()
        }
        composable(Page.Profile.route){
            ProfilePage()
        }
        /*
        =============================================
        */
 
        composable(Page.Player.route, Song song){ // unresolved reference: song
            PlayerPage(song = song)
        }
        composable(Page.Search.route){
            SearchPage()

        }
    }
}

我正在考虑使用 bacStackEntry 将对象发送到所需的可组合对象,而不是将其转换为 json 字符串并将其作为字符串传递。

我该如何解决这个问题? 谢谢。

完整代码可在here获取

【问题讨论】:

    标签: android-jetpack-compose


    【解决方案1】:

    使用Gson, 只需将对象解析为 JSON,如下所示: Gson().toJson(myObj) 并将其作为字符串传递并在另一个屏幕上解析回您想要的对象Gson().fromJson(json,Object::class.java)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多