我正在使用 retrofit 和 ViewModel 概念通过 api 调用获取货币汇率。启动应用程序时,我能够从服务器获取最新数据,但是当我尝试更新实时
我正在使用 retrofit 和 ViewModel 概念通过 api 调用获取货币汇率。在启动应用程序时,我能够从服务器获取最新数据,但是当我尝试通过单击按钮来更新实时数据时,实时数据值不会更新,我得到的是相同的旧数据。所以有人可以帮我如何在按钮单击事件上更新实时数据吗?
类 MainViewModel(私有 val 存储库:CurrencyRepository):ViewModel(){
init {
viewModelScope.launch() {
repository.getCurrencyExchangeList()
}
}
val quotes: LiveData<CurrencyData>
get() = repository.currencyLiveData
}
类 CurrencyRepository(private val currencyService:CurrencyInterface){
val currencyLiveData = MutableLiveData<CurrencyData>()
suspend fun getCurrencyExchangeList() {
val result = currencyService.getAllCurrencyData()
if (result.body() != null) {
//currencyLiveData.postValue(result.body())
currencyLiveData.value = result.body()
}
}
}
私人乐趣 fetchCurrencyRates() {
val currencyService = RetrofitHelper.getInstance().create(CurrencyInterface::class.java)
val repository = CurrencyRepository(currencyService)
val mainViewModel =
ViewModelProvider(this, MainViewModelFactory(repository))[MainViewModel::class.java]
mainViewModel.quotes.observe(this, Observer {
Log.d("AllCurrencyList", it.updated)
})
}
我不知道这是否只是由复制粘贴错误引起的,但 dao getFlow
需要一个 LocalDateTime
参数,而在(我猜)视图模型中,您只能 getAllRecords
使用 Context
参数进行调用。不清楚这些函数是如何关联的,因此在我的回答的其余部分中,我将忽略它, getAllRecords
因为它似乎没有任何与当前问题相关的用途。
相反,我将概述如何更改 getFlow
的 minDate
参数,同时仍返回相同的 StateFlow。然后您可以根据实际代码进行调整。
解决方案是引入另一个流 - MutableStateFlow - 来存储 minDate。MutableStateFlow 就像一个变量,它表示一个可以更改的值,因此每当您想要更新 minDate 时,只需设置 MutableStateFlow 的值即可。由于 MutableStateFlow 也是一个流,因此您可以使用任何流转换函数转换其值。在这种情况下,您希望用从中返回的流切换流 getFlow
.
假设您想要在视图模型中公开数据库流并使用它来更新参数, minDate
那么我上面描述的内容可能如下所示:
class MyViewModel(
dao: MyDao,
) : ViewModel() {
private val minDate = MutableStateFlow<LocalDateTime?>(null)
val items: StateFlow<List<ItemModel>> = minDate
.flatMapLatest {
if (it == null) flowOf(emptyList())
else dao.getFlow(it)
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = emptyList(),
)
fun updateMinDate(date: LocalDateTime) {
minDate.value = date
}
}
这 minDate
是新的 MutableStateFlow。它用作属性的基础 items
,并 flatMapLatest
用于根据 minDate
的内容切换到另一个流。 Flow<LocalDateTime>
使用 MutableStateFlow 的值作为参数 Flow<List<ItemModel>>
进行调用, getFlow
为
然后,该流将转换为 StateFlow,可供 UI 收集。您应该为此使用, viewModelScope
而不是其他范围。请注意,您不需要在此处切换到 IO 调度程序,这是由 Room 库内部完成的。
现在,无论何时调用, updateMinDate
流程 items
都会自动更新此新日期。此外,数据库中的任何更改都会导致 StateFlow 更新。这是在不离开流程世界的情况下修改流程的常用方法。