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

gojuced7  于 2024-01-04  发布在  Android
关注(0)|答案(1)|浏览(205)

在提供的设置中,我在Jetpack Compose应用程序中在屏幕1和屏幕2之间导航时遇到了一个问题。下面是问题的详细信息:
在屏幕1上,我有一个TextField,它更新viewModel,并在screen1_1中显示更新后的viewModel.uiState.name,因为viewModel状态是作为参数传入的

  1. screen1_1(
  2. name = viewM.uiState.name
  3. )

字符串
当我单击屏幕2按钮时,它导航到屏幕2并显示通过navController传递的正确名称。navigate(“screen 2/${viewM.uiState.name}”)
但是,当我单击从屏幕2导航到屏幕1时,screen1_1重置为空?
当我导航回屏幕1时,如何保持viewModel状态

  1. NavHost(navController = navController, startDestination = "screen1") {
  2. composable("screen1") { screen1(navController) }
  3. composable("screen2/{name}") { backStackEntry ->
  4. val name = backStackEntry.arguments?.getString("name") ?: ""
  5. screen2(navController, name)
  6. }
  7. }
  8. @Composable
  9. fun screen1(navController: NavHostController) {
  10. val viewM: MyView = viewModel()
  11. Column {
  12. TextField(value = viewM.uiState.name, onValueChange = { viewM.updateName(it) })
  13. screen1_1(
  14. name = viewM.uiState.name
  15. )
  16. Button(onClick = { navController.navigate("screen2/${viewM.uiState.name}") }) {
  17. Text(text = "screen 2")
  18. }
  19. }
  20. }
  21. @Composable
  22. fun screen1_1(name: String) { Text(text = "Hello1 $name!") }
  23. @Composable
  24. fun screen2(navController: NavHostController, name: String) {
  25. Column {
  26. Text(text = "Name: $name", style = MaterialTheme.typography.bodyLarge)
  27. Spacer(modifier = Modifier.height(16.dp))
  28. Button(onClick = { navController.navigate("screen1") }) {
  29. Text(text = "Navigate to Screen 1")
  30. }
  31. }
  32. }
  33. data class MyData(var name: String = "")
  34. class MyView(private val state: SavedStateHandle) : ViewModel() {
  35. @OptIn(SavedStateHandleSaveableApi::class)
  36. var uiState by state.saveable {
  37. mutableStateOf(MyData(""))
  38. }
  39. private set
  40. fun updateName(name: String) {
  41. this.uiState = uiState.copy(name = name)
  42. }
  43. }

ijnw1ujt

ijnw1ujt1#

当您在screen2中运行navController.navigate("screen1")时,您实际上并没有返回到screen1,而是启动了一个新的screen1,因此使用navController.navigateUp()代替navController.navigate("screen1")

相关问题