目前我有一个ViewPager2
片段(作为起始目的地),包含两个子片段:ActiveOrderFragment
and CompletedOrderFragment
,他们都有自己的ViewModel
处理 api 调用(获取活动订单和已完成订单)。
当用户单击订单项时,它将导航到OrderEditorFragment
,并且有一个“将项目设置为活动/已完成”按钮,单击该按钮将更新订单的状态(只需一个PUT请求),然后返回ViewPager2
分段。
为了通知和刷新ActiveOrderFragment
and CompletedOrderFragment
,我创建了一个SharedFlow
in OrderViewModel
,这是一个共享的ViewModel
:
class OrderViewModel(application: Application) : AndroidViewModel(application) {
private val uiScope = viewModelScope
private val _isOrderStatusChanged = MutableSharedFlow<Boolean>(replay = 1)
val isOrderStatusChanged: SharedFlow<Boolean>
get() = _isOrderStatusChanged
fun updateIsOrderStatusChanged() = _isOrderStatusChanged.emit(uiScope, true)
}
然后我观察(收集)这个SharedFlow
in onCreateView()
of ActiveOrderFragment
and CompletedOrderFragment
:
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
orderViewModel.isOrderStatusChanged.collect {
if (it) {
Log.v("xxx", "refreshed!")
viewModel.refreshActiveOrders() //similar in CompletedOrderFragment
}
}
}
}
问题来了:当我更改状态并返回页面时,它们都会收到通知并刷新。然而,现在我点击任意订单项进入编辑器页面,但什么也不做,然后返回,collect{}
再次被调用,这不是预期的行为。如何预防呢?我想这与replay
财产...
一些额外的信息:
- Why use viewLifecycleOwner代替lifecycleScope直接地。 https://stackoverflow.com/q/67422182/3466808
- 为什么需要replay = 1 for SharedFlow. https://stackoverflow.com/a/70262955/3466808
MutableSharedFlow<Boolean>(replay = 1) == MutableStateFlow<Boolean>(false)
重播是什么意思
MutableSharedFlow<Boolean>(replay = 0)
什么也没抓到
MutableSharedFlow<Boolean>(replay = 1)
捕获最新值
MutableSharedFlow<Boolean>(replay = 2)
捕获最新的 2 个值
orderViewModel.isOrderStatusChanged.collect {
Log.i("isOrderStatusChanged","$it")
}
如果你用 diff 值设置 _isOrderStatusChanged 两次,你就会发现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)