NaaleinGrohiik
NaaleinGrohiik

Reputation: 75

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
    }
}

Upvotes: 1

Views: 2698

Answers (1)

iamanbansal
iamanbansal

Reputation: 2742

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

Upvotes: 3

Related Questions