Areyana
Areyana

Reputation: 385

Paging Library doesn't trigger observe when load initial data

I'm setting up paged list of items that i fetch in datasource with coroutines, also i'm observing this list to submit it in adapter, but when it initially loads some data, it does not trigger observe callback. What can i do to handle this ?

I tried to debug this thing, and i found that ArrayList> mCallbacks list in PagedList, does not contain any callbacks when it tried to notify data changes, but i don't know what to do with this.

Data source from data will be fetched and paged.

class PagedDataSource(private val account: Account, private val getItems: GetItems): PageKeyedDataSource<Int, Item>() {

    override fun loadInitial(
        params: LoadInitialParams<Int>,
        callback: LoadInitialCallback<Int, Transaction>
    ) {
        GlobalScope.launch {
            val startPage = 0
            account.id?.let {
                val items = getItems(it, startPage).body.toMutableList()
                callback.onResult(items, null, 1)
            }
        }
    }

    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Item>) {
        GlobalScope.launch {
            account.id?.let {
                val list = getItems(it, params.key)
                val items = list.body.toMutableList()
                callback.onResult(items, if (params.key >= list.totalPages) null else params.key + 1)
            }
        }
    }

    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Item>) {
        //NO NEED
    }

}

code in fragment:

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

        vItems.layoutManager = LinearLayoutManager(context)
        vItems.isNestedScrollingEnabled = false
        vItems.adapter = pagedAdapter

                   items.observe(viewLifecycleOwner, Observer { items ->
                if (items != null && items.isNotEmpty()) {
                   pagedAdapter.submitList(items)
                } else {
                    vItemsTitle.visibility = View.VISIBLE
                }
            })
}

And finally code in my viewmodel

    init {
        items = initializedPagedList()
    }

    private fun initializedPagedList() : LiveData<PagedList<Item>> {
        val factory = object: DataSource.Factory<Int, Item>() {
            override fun create(): DataSource<Int, Item> {
                return PagedDataSource(account, getItems)
            }
        }
        val config = PagedList.Config.Builder()
            .setPageSize(20)
            .setEnablePlaceholders(false)
            .build()

        return LivePagedListBuilder(factory, config).build()
    }

I expect that data will be fetched after success api calls in loadInitial method and trigger observe callback.

Upvotes: 3

Views: 5286

Answers (1)

Areyana
Areyana

Reputation: 385

Finally after researching, i found answer for my question.


Problem was in this code

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

    vItems.layoutManager = LinearLayoutManager(context)
    vItems.isNestedScrollingEnabled = false
    vItems.adapter = pagedAdapter

               items.observe(viewLifecycleOwner, Observer { items ->
            if (items != null && items.isNotEmpty()) {
               pagedAdapter.submitList(items)
            } else {
                vItemsTitle.visibility = View.VISIBLE
            }
        })
 }

I needed to change this to

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

    vItems.layoutManager = LinearLayoutManager(context)
    vItems.isNestedScrollingEnabled = false
    vItems.adapter = pagedAdapter

               items.observe(viewLifecycleOwner, Observer { items ->
               pagedAdapter.submitList(items)
        })
 }

I think that's happening because in foreground PagedList works asynchronously/ and you need to submit this list once and after that datasource will send updates directly to the adapter, avoiding observing. In my case i'm submiting if list is not empty, but it will always empty when you're creating PagedList at the start.

Good luck everyone !

Upvotes: 3

Related Questions