gpt4 book ai didi

Android Jetpack Compose (Composable) 从 Coroutine 获取 String 资源

转载 作者:行者123 更新时间:2023-12-05 00:14:36 28 4
gpt4 key购买 nike

我有一个封装了一个密封类的流,用于向 UI 调用消息。例如显示一个 Snackbar。我可以使用 LaunchedEffect 观察来自 Composable 的 Flow。但问题是我想从协程范围内检索字符串资源。而且我不想在我的 View 模型中使用直接字符串值,因为我想将 Locale 用于不同的语言,所以我改为传递 String Res Id。那么有没有一种很好的方法来做到这一点,而无需将字符串资源放在 Application 类中并从那里检索它们,如这里所描述的 getString Outside of a Context or Activity
下面的代码:

  • 我有 Scaffold 用于显示 snackbar ,当用户单击填充整个屏幕的脚手架时,会调用 showSnackbarWithScope 方法,该方法会向 Flow 发出新值。
  • 然后通过 LaunchedEffect
  • 捕获更改
  • 然后它使用消息调用 showSnackbar() 方法,但该函数需要 String 并且我有 String Res Id (Int) 值
  • 我无法使用从可组合范围检索字符串的 stringResource() 方法的问题,因为我在协程

  • @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(true) {
    context.resources.getString(event.messageResId)
    }

    关于Android Jetpack Compose (Composable) 从 Coroutine 获取 String 资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70922868/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com