如何在 Jetpack Compose 中将视图模型从一个屏幕共享到另一个屏幕?

How can I share viewmodel from one screen to another screen in jetpack compose?

我正在尝试学习 android jetpack compose,我有简单的应用程序。在 ScreenA 中,我有一个文本字段,当我单击按钮时,我将此数据保存到 firestore,当我进入 ScreenB 时,我也想在 firebase 中保存城市名称,但我使用的是一个视图模型,那么如何保存两个文本字段数据都在 firestore 的同一个地方,我没有找到任何解决方案。

屏幕A:

    class ScreenAActivity : ComponentActivity() {



    private lateinit var  viewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
     
        viewModel = ViewModelProvider(this)[MyViewModel::class.java]


        setContent {
            ScreenA(viewModel)
        }
     }
   }

  @Composable
  fun ScreenA(

  viewModel : MyViewModel

  ) {

   val name = remember { mutableStateOf(TextFieldValue()) }

      OutlinedTextField(
            value = name.value,   
            onValueChange = { name.value = it },
            label = { Text(text = "name") },
          
        )

        Button(
            modifier = Modifier
                .width(40.dp)
                .height(20.dp),
            onClick = {

                focus.clearFocus(force = true)
                viewModel.onSignUp(
                    name.value.text,
                 
                )
                context.startActivity(
                    Intent(
                        context,
                        ScreenB::class.java
                    )
                )

                },
            colors = ButtonDefaults.buttonColors(
                backgroundColor = Color.Red
            ),
            shape = RoundedCornerShape(60)
        ) {
            Text(
                text = "OK"
             
             )
            )
        }

 }

屏幕B:

class ScreenBActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)

    setContent {
        ScreenB()
    }
 }
}

@Composable
fun ScreenB(

 ) {
val city = remember { mutableStateOf(TextFieldValue()) }

  OutlinedTextField(
        value = city.value,   
        onValueChange = { city.value = it },
        label = { Text(text = "city") },
      
    )

    Button(
        modifier = Modifier
            .width(40.dp)
            .height(20.dp),
        onClick = {

            focus.clearFocus(force = true)
            viewModel.onSignUp(
                city.value.text,
             
            )
           

            },
        colors = ButtonDefaults.buttonColors(
            backgroundColor = Color.Red
        ),
        shape = RoundedCornerShape(60)
    ) {
        Text(
            text = "OK"
         
         )
        )
    }

   }

建议使用单个 activity 并使用 Navigation library 在屏幕中导航。

重构代码以使用导航库后,您可以传递之前的返回堆栈条目以获得相同的视图模型实例。

val navController = rememberNavController()
NavHost(
    navController = navController,
    ...
) { 
    composable("ScreenA") { backStackEntry ->
        val viewModel: MyViewModel = viewModel(backStackEntry)
        ScreenA(viewModel)
    }
    composable("ScreenB") { backStackEntry ->
        val viewModel: MyViewModel = viewModel(navController.previousBackStackEntry!!)
        ScreenB(viewModel)
    }
} 

但是如果您确实需要使用 activity 来执行此操作,我的建议是在视图模型之间定义一个共享对象。类似于:

object SharedSignInObject {
    fun signUp(name: String) {
        // do something
    }
    // other things you need to share...
}

并且在您的视图模型中,您可以使用此对象...

class MyViewModel: ViewModel() {
    fun signUp(name: String) {
        SharedSignInObject.signUp(name)
    }
}