Search code examples
androidkotlinkotlin-coroutineskotlin-flowandroid-paging-3

android paging 3 line after adapter.submitData doesn't get executed


I am currently learning Paging 3 library. I have an app that has shimmer placeholder for showing while loading the data. When i get the data i want to hide shimmer layout and show recycler view.

lifecycleScope.launch {
            quoteViewModel.getQuotes2().collectLatest {
                binding.shimmerLayout.visibility = View.GONE // this line gets executed when view created and it causes shimmer layout to hide
                binding.homeRecyclerView.visibility = View.VISIBLE
                homeAdapter.submitData(it)
                Log.d("mytag", "after submit data") // this line isn't executed
            }
        }

Problem here is the line after the submitData doesn't get executed.I searched and saw the reason was because submitData never returns so it doesn't get called. But i didn't find any example code. Can someone please show me an example code for solving this?

The logic i want to execute after submitData is to hide shimmerLayout and show recyclerView, but because that logic is before submit data, they are executed immediately, therefore shimmerLayout doesn't seem when loading data.


Solution

  • As you mentioned, it is true that the line after submitData() won't be executed since it doesn't return. What is it exactly that you are wanting to achieve using Paging 3 with it here?

    I had a similar doubt where my recyclerview was not updating data fetched from Paging 3 because I was using collect operator. Dustin Lam, the author of Paging 3 library answered me here to replace the collect with collectLatest and that had fixed the issue for me.

    In your case, you are already using collectLatest. One quick fix can be to put the submitData at the very end of collectLatest since that is what causes the issue.

    As mention in the collectLatest definition,

    Terminal flow operator that collects the given flow with a provided action. The crucial difference from collect is that when the original flow emits a new value then the action block for the previous value is cancelled.

    Note that replacing collect with collectLatest fixed the issue for my case only because initially my StateFlow was emitting an Initial state, but when the data was ready, it emitted a Success state that wasn't collected by the collect operator since the submitData never returns, but collectLatest forces the previous action block to be cancelled and new value to be collected.

    I'm unsure of a solution to your problem yet but either edit your question with the exact use case or in case you do not find any alternative to it, you can directly ask Dustin Lam about it like I did :)