我目前面临以下问题,希望有人能够提供帮助:
我的 ViewModel 中有一个
flow
,它为我提供了一些数据。现在我希望从 ui 上拉刷新时重新加载此数据,但我不确定重新触发流程或重新加载数据的最佳方法是什么。
也许有一个例子可以说明我的意思:
我有以下视图模型:
class MyViewModel(
getSomeDataUsecase : GetSomeDataUseCase
): ViewModel(){
val myData:Flow<SomeData> = getSomeDataUsecase() // <-- this returns a flow and emits the data
fun refreshData(){
// TODO: retrigger "getSomeDataUsecase" to load new data and provide them at "myData"
}
}
现在我想在下拉刷新时再次触发查询
getSomeDataUsecase
,这应该通过方法refreshData
来完成。然而,从那里,我不知道如何最好地继续。
有人遇到同样的问题吗?我很想知道你是如何解决的。
提前致谢:)
您现在使用流程的方式并不是它们应该使用的方式。您正在使用流作为单个请求的回调。流程应该是订阅,并且任何时候数据更改都会提交到流程。
使用上面的代码应该是这样的
class MyViewModel(
getSomeDataUsecase : GetSomeDataUseCase
): ViewModel(){
private val _mutableMyData:MutabelStateFLow<SomeData> = MutableStateFlow<SomeData>(initialData)
val myData:StateFlow<SomeData> = _mutableMyData.asStateFlow()
suspend fun refreshData(){
val newData = getSomeDataUsecase()
_mutableMyData.emit(newData)
}
}
然后在您的活动中收集流量
suspend fun listenForFlowUpdates(){
viewModel.myData.collect{data ->
//Called when new data is submitted to the flow
//Update UI and stop your pull to refresh or whatever else
}
}
然后你所要做的就是从任何地方调用视图模型中的
refreshData()
,你应该获取数据
我不知道为什么我之前无法得到它,所以感谢大家的回复:D .
这是我现在处理手动触发刷新的解决方案:
class MyViewModel(
getSomeDataUsecase : GetSomeDataUseCase
): ViewModel(){
private val forceRefreshAction = MutableSharedFlow<Boolean>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)
val myData:Flow<SomeData> = forceRefreshAction
.onStart {
emit(false)
}
.flatMapLatest { forceRefresh ->
getSomeDataUsecase() // <-- this returns a flow and emits the data
}
.flowOn(dispatcher.io)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000, replayExpirationMillis = 5000),
initialValue = SomeData(),
)
fun refreshData(){
forceRefreshAction.tryEmit(true) // <-- Called from UI on pull-to-refresh
}
}