如何将结果从viewModelScope传递到activity

问题描述 投票:0回答:1

我想将 viewModelScope 的结果传递到我的活动中。我创建了 viewModel,它有 2 个方法。

class CurrencyConverterViewModel : ViewModel() {

    lateinit var response: CurrencyCodesModel
    var listOfNames : List<String> = emptyList()

    init {
        viewModelScope.launch {
            getListOfCurrencyNamesApi()
        }
    }

    suspend fun getCurrencyCodes() {
        response = CurrencyConverterInstance
            .currencyApiService
            .getCurrencyCodes()
    }
    private suspend fun getListOfCurrencyNamesApi() {

        getCurrencyCodes()

        listOfNames = response.supported_codes.map { it[1] }
    }
}

其中一个调用我的 api 服务并将结果存储在 response 变量中。名为 getListOfCurrencyNamesApi 的第二个方法应该从 response 中获取 supported_codes 并将它们拆分为字符串列表。

然后我在 Composable 函数中创建 viewModel 对象。此时,viewModel 中的 init 函数被调用,我在 Logcat 中看到该列表有一些记录,但是当我想将其放入 currencyListOfNames.value 时,它是空的

@Composable
fun CurrencyConverter() {

    val myViewModel: CurrencyConverterViewModel = viewModel()
    val currencyListOfNames = remember { mutableStateOf<List<String>>(emptyList()) }

    currencyListOfNames.value = myViewModel.listOfNames
}
android kotlin viewmodel kotlin-coroutines
1个回答
0
投票

这里有一个解决方案可以帮助您解决问题,您没有看到数据更新的原因是因为它们位于不同的线程中,因此您无法知道您的可组合项正在更新并且已更新又重新组合了。

class CurrencyConverterViewModel : ViewModel() {

    lateinit var response: CurrencyCodesModel
    // Here you are creating the variable with a stateFlow but you can also do it with a SharedFlow the difference you can see here https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
    private var _listOfNames = MutableStateFlow<List<String>>(listOf())
    val  listOfNames = _listOfNames.asStateFlow()

    init {
        viewModelScope.launch {
            getListOfCurrencyNamesApi()
        }
    }

    suspend fun getCurrencyCodes() {
        response = CurrencyConverterInstance
            .currencyApiService
            .getCurrencyCodes()
    }
    private suspend fun getListOfCurrencyNamesApi() {

        getCurrencyCodes()
        //here you update the change 
        _listOfNames.emit(
            response.supported_codes.map { it[1] }
        )
    }
}

@Composable
fun CurrencyConverter() {
    val myViewModel: CurrencyConverterViewModel = viewModel()
    //Here every time you call your getCurrencyCodes function and issue _listOfNames your composable will recompose and update the data.
    val listOfNames by myViewModel.listOfNames.collectAsState()
}
© www.soinside.com 2019 - 2024. All rights reserved.