我想将 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
}
这里有一个解决方案可以帮助您解决问题,您没有看到数据更新的原因是因为它们位于不同的线程中,因此您无法知道您的可组合项正在更新并且已更新又重新组合了。
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()
}