簡體   English   中英

使用 repeatOnLifecycle 收集 StateFlow 的值,但僅在當前片段恢復時接收更新

[英]Use repeatOnLifecycle to collect a StateFlow's value but only receive the update when current fragment resume

當我在 repeatOnLifecycle 中收集 StateFlow 的值時,我必須導航到其他片段然后返回才能收集值的變化。 但是,一旦更改了值,收集 lambda 就不會立即收到更改,而不會恢復當前片段。 我該如何解決這個問題?

// Dao.kt
@Dao
interface AppDao {
    // other codes

    @Query("SELECT * FROM Property")
    fun getAllProperties(): Flow<List<Property>>
    
    // other codes
}

帶有 Singleton 模式的存儲庫,並提供上述 AppDao 中的功能。

視圖模型:

class PropertyViewModel : ViewModel() {
    private val repository = AppRepository.get()

    private val _properties: MutableStateFlow<List<Property>> = MutableStateFlow(emptyList())
    val properties: StateFlow<List<Property>> = _properties
    // or ⬇️ this way still not work
    // val properties: StateFlow<List<Property>>
    //    get() = _propertis.asStateFlow()

    init {
        viewModelScope.launch {
            repository.getAllProperties().collect {
                _properties.value = it
            }
        }
    }

    // other codes
}

分段:

class SomeFragment : Fragment() {

    private var _binding: FragmentPropertyBinding? = null

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    private val propertyViewModel: PropertyViewModel by viewModels()

    // onCreate lifecycle method here

    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // other codes

        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.lifecycleScope.repeatOnLifecycle(Lifecycle.State.CREATED) {
                propertyViewModel.properties.collect { propertis: List<Property> ->
                    // 🔴 Here I can only collet the propertis list when I go to other framgent/ or Home and then back to this fragment
                    // todo something
                }
            }
        }

        propertyViewModel.properties
            .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.CREATED)
            .onEach {
                // 🔴 and this way is identical to the repeatOnLifecycle method
                Log.e("Database flowWithLifecycle", it.toString())
            }
            .launchIn(viewLifecycleOwner.lifecycleScope)

    }

    // other override lifecycle methods
}

一旦更改了值而不離開當前片段並返回,我如何修改代碼以收集值?

使用不同的 lifecycleScope 測試收集並確認 ViewModel 中的值在修改后收集了最新值。

期望在不離開當前片段並返回的情況下更改其值后收集片段中的值?

StateFlow具有強大的基於相等性的合並, 來自文檔

state 流中的值以與 distinctUntilChanged 運算符類似的方式使用 Any.equals 比較進行合並。 它用於將傳入的更新合並到 MutableStateFlow 中的值,並在新值等於先前發出的值時抑制向收集器發出值。 State 未指定違反 Any.equals 約定的類的流行為。

將它與可變數據類型一起使用可能會導致問題。 我建議切換到不可變數據類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM