Note- 这个问题与this one https://stackoverflow.com/q/68496045/9636037.
我正在寻找更好的方法(如果有的话)。
As per 安卓文档 https://developer.android.com/jetpack/guide/ui-layer/events#consuming-trigger-updates,
一旦显示了瞬时消息,UI 需要通知
ViewModel 的,导致另一个 UI 状态更新:
例如,当我在单击按钮时显示 Toast 消息时,UI 是否应该通知 ViewModel Toast 已成功显示?
这是处理诸如吐司、小吃店等一次性操作的最佳方法吗?
示例代码,
@Composable
fun OneShotOperation(
viewmodel: OneShotOperationViewModel = viewModel(),
) {
val context = LocalContext.current
LaunchedEffect(
key1 = viewmodel.toastMessage,
) {
if (viewmodel.toastMessage.isNotBlank()) {
Toast.makeText(
context,
viewmodel.toastMessage,
Toast.LENGTH_SHORT,
).show()
viewmodel.toastMessage = "" // Is this the correct way?
}
}
Button(
onClick = {
viewmodel.toastMessage = "Sample Toast"
},
) {
Text(text = "Show Toast")
}
}
class OneShotOperationViewModel : ViewModel() {
var toastMessage by mutableStateOf(
value = "",
)
}
如果我删除这一行,
viewmodel.toastMessage = "" // Is this the correct way?
Toast 仅显示一次,随后按下按钮不会显示 Toast,因为可变状态尚未更改。
我更喜欢使用SharedFlow
对于这样的工作。
请注意,如果您从另一个视图发送消息collect
没有运行,当你最终启动它时,它不会显示 toast。它不存储该值,仅将其传递给当前连接的所有收集器。
class OneShotOperationViewModel : ViewModel() {
private val _toastMessage = MutableSharedFlow<String>()
val toastMessage = _toastMessage.asSharedFlow()
fun sendMessage(message: String) {
viewModelScope.launch {
_toastMessage.emit(message)
}
}
}
@Composable
fun TestScreen() {
val context = LocalContext.current
val viewModel = viewModel<OneShotOperationViewModel>()
LaunchedEffect(Unit) {
viewModel
.toastMessage
.collect { message ->
Toast.makeText(
context,
message,
Toast.LENGTH_SHORT,
).show()
}
}
Button(
onClick = {
viewModel.sendMessage("Sample Toast")
},
) {
Text(text = "Show Toast")
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)