简体   繁体   English

Kotlin Flow.collect 执行但不更新 ui onConfigurationChanged

[英]Kotlin Flow.collect executes but does not update ui onConfigurationChanged

I'm using Flow to get data from Room then I call Flow.collect in my FragmentLogic class. Inside collect{} I do some work and update the View through an Interface( example: view.updateAdapter(collectData) ).我正在使用Flow从 Room 获取数据,然后在我的 FragmentLogic class 中调用Flow.collect 。在collect{}内部我做了一些工作并通过接口更新视图(示例: view.updateAdapter(collectData) )。 This works fine until an onConfigurationChanged is called and the screen rotates, the code inside collect executes and works in Logcat but anything that changes the UI does not work, the function updateAdapter() is called however nothing happens.这在调用onConfigurationChanged并且屏幕旋转之前工作正常,collect 中的代码在 Logcat 中执行并工作,但任何更改 UI 的内容都不起作用,function updateAdapter()被调用但没有任何反应。 One solution I found is to call the function beginObservingProductList() again in onStart() if savedinstance is not null but that creates two instances of the collect{} and they both show in logcat.我发现的一种解决方案是在onStart() ) 中再次调用 function beginObservingProductList() ) 如果 savedinstance 不是 null 而是创建 collect{} 的两个实例并且它们都显示在 logcat 中。

I want the UI changes to work even after onConfigurationChanged is called.我希望即使在onConfigurationChanged后 UI 更改也能正常工作。

Room Dao class:房道class:

@Query("SELECT * FROM product")
fun observableList(): Flow<List<ProductEntity>>

then in the implementation:然后在实现中:

 productDao.observableList().map { collection ->
            collection.map { entity ->
                entity.toProduct
            }
 }.flowOn(DispatchThread.io())

And finally I collect the data and change the view:最后我收集数据并更改视图:

 private fun beginObservingProductList() = this.launch {
    vModel.liveProductList.map {
        mapToSelectionProduct(it)
 }.collect {
        ui { view.updateAdapter(it) }
        if (it.isNotEmpty()) {
            filledListState()
     } else {
            emptyListState()
     }
        updateCosts()
        vModel.firstTime = false
    }
}

Flow is not lifecycle aware, you should use LiveData to handle configuration changes. Flow 不具备生命周期感知能力,您应该使用LiveData来处理配置更改。

To use LiveData with Flow, implement androidx.lifecycle:lifecycle-livedata-ktx:2.2.0 , then you can use .asLiveData() extension func.要将 LiveData 与 Flow 一起使用,请实现androidx.lifecycle:lifecycle-livedata-ktx:2.2.0 ,然后您可以使用.asLiveData()扩展函数。

Repository存储库

fun getList()= productDao.observableList().map { collection ->
        collection.map { entity ->
            entity.toProduct
        }
}.flowOn(DispatchThread.io())

ViewModel视图模型

val liveData = repository.getList().asLiveData()

Activity/Fragment活动/片段

 viewModel.liveData.observe(this,Observer{ list->

//do your thing
})

You should use repeatOnLifecycle as suggested by Google.您应该按照 Google 的建议使用 repeatOnLifecycle 。

在此处输入图片说明

Link: https://developer.android.com/kotlin/flow/stateflow-and-sharedflow链接: https : //developer.android.com/kotlin/flow/stateflow-and-sharedflow

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM