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

4 android kotlin android-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"
             
             )
            )
        }

 }
Run Code Online (Sandbox Code Playgroud)

屏幕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"
         
         )
        )
    }

   }
Run Code Online (Sandbox Code Playgroud)

ngl*_*ber 5

建议使用单个活动并使用导航库在屏幕之间导航。

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

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)
    }
} 
Run Code Online (Sandbox Code Playgroud)

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

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

在你的视图模型中你可以使用这个对象......

class MyViewModel: ViewModel() {
    fun signUp(name: String) {
        SharedSignInObject.signUp(name)
    }
}
Run Code Online (Sandbox Code Playgroud)