如何在 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)
}
}
我正在尝试学习 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)
}
}