因此,基本上,在snackbar操作按钮上,如果用户单击Retry,我想重试API调用。
我使用了具有Flow的核心MVVM架构。我甚至还使用了视图模型和视图之间的流。请注意,我已经在视图和ViewModel之间使用了livedata,但是现在需求已经改变了,我只能使用Flow。此外,我也不使用和共享或状态流,这不是必需的。
代码:片段:
private fun apiCall() {
viewModel.fetchUserReviewData()
}
private fun setObservers() {
lifecycleScope.launch {
viewModel.userReviewData?.collect {
LogUtils.d("Hello it: " + it.code)
setLoadingState(it.state)
when (it.status) {
Resource.Status.ERROR -> showErrorSnackBarLayout(-1, it.message, {
// Retry action button logic
viewModel.userReviewData = null
apiCall()
})
}
}
}视图模型:
var userReviewData: Flow<Resource<ReviewResponse>>? = emptyFlow<Resource<ReviewResponse>>()
fun fetchUserReviewData() {
LogUtils.d("Hello fetchUserReviewData: " + userReviewData)
userReviewData = flow {
emit(Resource.loading(true))
repository.getUserReviewData().collect {
emit(it)
}
}
}在ViewModel中编辑:
// var userReviewData = MutableStateFlow<Resource<ReviewResponse>>(Resource.loading(false))
var userReviewData = MutableSharedFlow<Resource<ReviewResponse>>()
fun fetchUserReviewData() {
viewModelScope.launch {
userReviewData.emit(Resource.loading(true))
repository.getUserReviewData().collect {
userReviewData.emit(it)
}
}
}
override fun onCreate() {}}
在活动中编辑:
private fun setObservers() {
lifecycleScope.launchWhenStarted {
viewModel.userReviewData.collect {
setLoadingState(it.state)
when (it.status) {
Resource.Status.SUCCESS ->
if (it.data != null) {
val reviewResponse: ReviewResponse = it.data
if (!AppUtils.isNull(reviewResponse)) {
setReviewData(reviewResponse.data)
}
}
Resource.Status.ERROR -> showErrorSnackBarLayout(it.code, it.message) {
viewModel.fetchUserReviewData()
}
}
}
}
}现在,我只有一个疑问,我是使用状态1还是共享状态?我看到菲利普拉克纳视频和理解的区别,但仍在考虑使用什么!
问题是我们只支持面向肖像,但是未来的需求会是什么呢?在这种情况下,我认为我必须使用state one,这样它才能在配置更改中存活下来!不知道该怎么办!
发布于 2022-09-02 17:30:57
由于单一责任原则,ViewModel应该单独更新其流以显示最新的请求数据,而不是必须取消正在进行的请求并从片段端重新订阅新的请求。
这是你可以做的一种方法。使用MutableSharedFlow触发获取请求,使用flatMapLatest重新启动新请求的下游流。
通道也可以用作触发器,但它与MutableSharedFlow相比要简洁一些。
//In ViewModel
private val fetchRequest = MutableSharedFlow<Unit>(replay = 1, BufferOverflow.DROP_OLDEST)
var userReviewData = fetchRequest.flatMapLatest {
flow {
emit(Resource.loading(true))
emitAll(repository.getUserReviewData())
}
}.shareIn(viewModelScope, SharingStarted.WhlieSubscribed(5000), 1)
fun fetchUserReviewData() {
LogUtils.d("Hello fetchUserReviewData: " + userReviewData)
fetchRequest.tryEmit(Unit)
}上面的现有片段代码应该可以使用这一点,但是您不再需要?空安全调用,因为流是不可空的。
但是,,,如果协同线对视图做了任何操作,则应该使用viewLifecycle.lifecycleScope而不是仅使用lifecycleScope。
https://stackoverflow.com/questions/73565830
复制相似问题