Reputation: 385
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
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