android-fragments Android片段从共享视图收集SharedFlow模型问题

mhd8tkvw  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(174)

目前我有一个ViewPager2 Fragment(作为起始目的地),它包含两个子Fragment:ActiveOrderFragmentCompletedOrderFragment,它们都具有它们自己的ViewModel来处理API调用(以获得活动订单和完成的订单)。
当用户单击订单项时,它将导航到OrderEditorFragment,并且有一个“Set Item as Active/Completed”按钮,单击该按钮将更新订单的状态(只是一个简单的PUT请求),并返回到ViewPager2片段。
为了通知和刷新ActiveOrderFragmentCompletedOrderFragment,我在OrderViewModel中创建了一个SharedFlow,它是一个共享的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)            
}

然后我在ActiveOrderFragmentCompletedOrderFragmentonCreateView()中观察(收集)这个SharedFlow

viewLifecycleOwner.lifecycleScope.launch {
    viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
        orderViewModel.isOrderStatusChanged.collect { 
            if (it) {
                Log.v("xxx", "refreshed!")
                viewModel.refreshActiveOrders()    //similar in CompletedOrderFragment
            }
        }
    }
}

问题来了:当我改变状态并返回页面时,它们都得到了通知和刷新。但是,现在我单击任何订单项以转到编辑器页面,但什么也不做,然后返回,再次调用collect{},这不是预期的行为。如何防止这种情况?我猜这与replay属性有关...
一些额外信息:

  1. Why use viewLifecycleOwner instead of lifecycleScope directly.
  2. Why need replay = 1 for SharedFlow .
ffscu2ro

ffscu2ro1#

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两次,您就会发现。

相关问题