我有一个封装密封类的 Flow,用于向 UI 调用消息。例如显示 Snackbar。我可以使用 LaunchedEffect 观察可组合项的流程。但问题是我想从协程范围中检索字符串资源。我不想在视图模型中使用直接字符串值,因为我想使用不同语言的区域设置,所以我传递了字符串 Res Id。那么有没有一种好的方法可以做到这一点,而无需将字符串资源放入应用程序类中并从那里检索它们,如此处所示getString Outside of a Context or Activity
以下代码:
@Composable
fun HomeScreen(viewModel: CityWeatherViewModel) {
val scaffoldState = rememberScaffoldState()
LaunchedEffect(true) {
viewModel.eventFlow.collectLatest { event ->
when (event) {
is CityWeatherViewModel.UIEvent.ShowSnackbar -> {
// THE PROBLEM IS HERE!!!, since event.messageResId is res id, and not the string resource, and I can not use stringResource from coroutine
scaffoldState.snackbarHostState.showSnackbar(
message = event.messageResId
)
}
}
}
}
Scaffold(
scaffoldState = scaffoldState,
modifier = Modifier
.fillMaxSize()
.clickable {
viewModel.showSnackbarWithScope(R.string.could_not_determine_location)
}
) {
}
}
@HiltViewModel
class CityWeatherViewModel @Inject constructor(
private val getCityWeather: GetCityWeather
) : ViewModel() {
// to show snackbar with error
private val _eventFlow = MutableSharedFlow<UIEvent>()
val eventFlow = _eventFlow.asSharedFlow()
suspend fun showSnackbar(stringResId: Int) {
_eventFlow.emit(
UIEvent.ShowSnackbar(stringResId)
)
}
fun showSnackbarWithScope(stringResId: Int) {
viewModelScope.launch {
showSnackbar(stringResId)
}
_eventFlowSwitch.value = !_eventFlowSwitch.value
}
sealed class UIEvent {
data class ShowSnackbar(val messageResId: Int) : UIEvent()
}
companion object {
// time in ms, before we request new data
const val DELAY_BEFORE_REQUEST = 1500L
}
}
您可以使用
Context
在任何可组合项中获取 LocalContext
,然后在 LaunchedEffect
中使用它来获取资源:
val context = LocalContext.current
LaunchedEffect(Unit) {
context.getString(event.messageResId)
}