Jetpack Compose:如何在屏幕之间导航时保留 ViewModel 状态?

问题描述 投票:0回答:1

在提供的设置中,我在 Jetpack Compose 应用程序的屏幕 1 和屏幕 2 之间导航时遇到问题。这是问题的细分:

在屏幕 1 上,我有一个 TextField,它更新 viewModel 并在 screen1_1 中显示更新后的 viewModel.uiState.name,因为 viewModel 状态作为 arg 传入

screen1_1(
    name = viewM.uiState.name
)

当我单击屏幕 2 按钮时,它会导航到屏幕 2 并显示通过 navController.navigate("screen2/${viewM.uiState.name}") 传递的正确名称

但是,当我单击从屏幕 2 导航到屏幕 1 时,screen1_1 重置为空?

当我导航回屏幕 1 时如何保留 viewModel 状态

NavHost(navController = navController, startDestination = "screen1") {
    composable("screen1") { screen1(navController) }
    composable("screen2/{name}") { backStackEntry ->
        val name = backStackEntry.arguments?.getString("name") ?: ""
        screen2(navController, name)
    }
}

@Composable
fun screen1(navController: NavHostController) {
    val viewM: MyView = viewModel()

    Column {
        TextField(value = viewM.uiState.name, onValueChange = { viewM.updateName(it) })
        screen1_1(
            name = viewM.uiState.name
        )
        Button(onClick = { navController.navigate("screen2/${viewM.uiState.name}") }) {
            Text(text = "screen 2")
        }
    }
}

@Composable
fun screen1_1(name: String) { Text(text = "Hello1 $name!") }

@Composable
fun screen2(navController: NavHostController, name: String) {
    Column {
        Text(text = "Name: $name", style = MaterialTheme.typography.bodyLarge)
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { navController.navigate("screen1") }) {
            Text(text = "Navigate to Screen 1")
        }
    }
}


data class MyData(var name: String = "")

class MyView(private val state: SavedStateHandle) : ViewModel() {
    @OptIn(SavedStateHandleSaveableApi::class)
    var uiState by state.saveable {
        mutableStateOf(MyData(""))
    }
    private set

    fun updateName(name: String) {
        this.uiState = uiState.copy(name = name)
    }
}
android android-jetpack-compose android-viewmodel jetpack-compose-navigation
1个回答
0
投票

当您在 screen2 中运行

navController.navigate("screen1")
时,您实际上并没有返回到 screen1,而是开始一个新的 screen1,因此不要使用导航,而是使用
navController.navigateUp

© www.soinside.com 2019 - 2024. All rights reserved.