简体   繁体   中英

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) ). 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. 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.

I want the UI changes to work even after onConfigurationChanged is called.

Room Dao 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.

To use LiveData with Flow, implement androidx.lifecycle:lifecycle-livedata-ktx:2.2.0 , then you can use .asLiveData() extension func.

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.

在此处输入图片说明

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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