提问人:Christina 提问时间:12/9/2022 最后编辑:z.g.yChristina 更新时间:12/9/2022 访问量:636
在 Jetpack Compose 中使用 ViewModel 实现 startActivity 的最佳实践
Best practice to implement startActivity using ViewModel in Jetpack Compose
问:
例如,我有一个简单的可组合函数
@Composable
fun TextExample(model: SomeViewModel = viewModel()) {
TextButton(onClick = { model.onClick() }) {
Text(text = "Test")
}
}
The SomeViewModel:
class SomeViewModel : ViewModel() {
private val _text = mutableStateOf("Test")
val text: String
get() = _text.value
fun onClick() {
if (text.isEmpty()) {
// TODO: need to start some activity
} else {
_text.value = ""
}
}
}
我单击此按钮,然后模型必须处理此单击。在某些情况下,我需要开始另一项活动。正确的方法是什么?
答:
1赞
z.g.y
12/9/2022
#1
可能有更好的方法,但你可以考虑我的。
Id 建议首先为“一次性事件”创建一个数据结构,如下所示Sealed Class
sealed class Events {
object ToActivityA: Events()
object ToActivityB: Events()
data class ToastMessage(val message: String): Events()
}
在 ViewModel 中声明一个将发出这些事件SharedFlow
private val _events = MutableSharedFlow<Events>()
val events: SharedFlow<Events> = _events
在你的例子中,从你的onClick viewmodel函数中发出一个事件,如下所示
fun onClick() {
if (text.isEmpty()) {
viewModelScope.launch {
_events.emit(Events.ToActivityA) // or ToActivityB, or for a Toast
}
} else {
_text.value = ""
}
}
现在在你的可组合项中,只需像这样观察它LaunchedEffect
LaunchedEffect(key1 = Unit) {
viewModel.events.collectLatest {
when (it) {
Events.ToActivityA -> {
// to activity A
}
Events.ToActivityB -> {
// to activity B
}
is Events.ToastMessage -> {
// show toast message
}
}
}
}
如果你还没有准备好调用startActivity,我建议你访问这篇文章作为参考。
评论
0赞
Christina
12/9/2022
您如何看待此解决方案可能会在警报对话框中扩展?现在我使用这种方式: private val _needShowAppVersionIsOutOfDateDialog = mutableStateOf(false) val needShowAppVersionIsOutOfDateDialog: Boolean get() = _needShowAppVersionIsOutOfDateDialog.value fun closeNeedShowAppVersionIsOutOfDateDialog() { _needShowAppVersionIsOutOfDateDialog.value = false }
0赞
z.g.y
12/9/2022
我认为是的,您也可以在我的对话答案中使用这种方法
评论