我正在使用导航组合,并且我试图将整个对象传递到下一个屏幕,因此我通过 hilt 使用共享的 ViewModel
,并创建了该对象的 mutablestate 变量并希望在下一个屏幕中获取其值。
像这样
var campaign = mutableStateOf<Campaign?>(null)
private set
fun addCampaign(campaign: Campaign){
this.campaign.value = campaign
}
其中 Campaign
只是一个数据类。
在我的导航屏幕中
LazyColumn (
content =
{
items(viewModel.campaignListCurrent){ campaign ->
CampaignItem(
image = campaign.brand?.image ?: "",
title = campaign.name ,
id = campaign.id ,
description =campaign.description ,
date =campaign.createdAt ) {
viewModel.addCampaign(
CampaignsViewModel.Campaign(...) // the "campaign" object is used to fill this
)
Timber.tag("CampaignObject").v(viewModel.campaign.value.toString())
viewModel.changed = true
navController.navigate(Screen.CampaignDetailsScreen.route)
}
}
})
当我记录数据时,我可以看到它已成功存储。但在下一个屏幕中,当我从同一个 ViewModel 获取数据时,它是空的。尽管它是一个可变状态并且应该改变它的值并且是可观察的,但我认为我根本没有得到可变状态行为,并且任何对其正确解释的链接将不胜感激。
val campaign by remember { viewModel.campaign }
Timber.v("CampaignDetailsScreen2: " + campaign.toString())
有人可以向我解释一下为什么它在这里不起作用,即使我使用了启动效果? 为什么不在这里改变它的值?
最佳答案
我设法通过在 NavGraph 中创建一个 SharedViewModel 实例来解决这个问题,以确保它是两个可组合函数中使用的相同实例。
@Composable
fun CampaignsScreen(
navController : NavController,
viewModel: CampaignsViewModel
) {
...
@Composable
fun CampaignDetailsScreen(
navController : NavController,
viewModel: CampaignsViewModel
) {
在我的 NavGraph 中,我将 ViewModel 作为 HiltViewmodel 在构造函数中传递,并从它传递到两个屏幕
@Composable
fun SetUpNavGraph (navController : NavHostController,
campaignViewModel: CampaignsViewModel = hiltViewModel()) {
...........
loginNavGraph(navController = navController)
homeNavGraph(navController = navController, campaignsViewModel = campaignViewModel)
}
}
在主 NavGraph 中,我传递了参数及其相同的实例
fun NavGraphBuilder.homeNavGraph(
navController : NavHostController,
campaignsViewModel: CampaignsViewModel
){
navigation(startDestination = Screen.HomeScreen.route, route = HOME_GRAPH_ROUTE) {
................
composable(Screen.Campaigns.route){
CampaignsScreen(navController = navController, viewModel = campaignsViewModel)
}
composable(Screen.CampaignDetailsScreen.route){
CampaignDetailsScreen(navController, viewModel = campaignsViewModel)
}
}
}
您可以使用 backstackEntry 和 PreviouseBackStack 来解决此问题,但如果您的对象中有 JSON 对象,则它将不起作用,因为您需要手动序列化和反序列化该对象,并且需要更多的时间和代码来实现相同的目标共享 ViewModel 传递 Parclized 对象的目标。直到 Google Solve 在 Compose Navigation 中传递 Parclized 对象之前,如果您的 paralyzed 对象中没有 JSON 对象,我建议您使用 backStack Entry,如果有,请在两个可组合函数之间使用共享 ViewModel。
关于android - 如何在Android compose中通过Navigation传递对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73599427/