Basically I have a paging data flow collected in a composable function:
val list = state.listFlow.collectAsLazyPagingItems()
Each item on the list has a call-to-action button that will enable/disable the view and update the UI of the corresponding item.
My question is, how can we update the visual state of the item without the need for calling refresh on the PagingData and therefore re-querying the API/database for updated data?
Also if user has scrolled through 5 pages or more I don't want to reload the whole content, changes can be local.
Any clues on how to achieve this?
This is almost impossible for Paging3, which requires immutable lists. See https://issuetracker.google.com/issues/160232968.
This problem bothered me for months and finally I decided to abandon Paging3 library and write my own paged list to avoid all these weird features. Most of the complexity of Paging3 is because it wants to encapsulate the paged list in one library, which needs the view layer and the model layer to work together.
This is the paged list I implemented: https://gist.github.com/FishHawk/6e4706646401bea20242bdfad5d86a9e
If your project does not have a deep dependency on the paging3 library, I highly recommend you try doing this.
Related
I would like to add some item in current paging data which already contains items. And shown in the list adapter.
I have tried to insertHeaderItem. But, when adding second item. Header is getting replaced by second item. I want to keep all item in the list. and update that list every time when i add new item.
paingData
.insertHeaderItem(item = sampleViewEvents.comment)
.let {
getCommentList.value = it
}
I doesn't want to call an API to refresh the whole list. It can leads a performance issue.
Thanks in advance
The correct way to add / modify items with Paging is to update the backing dataset and .invalidate(), refreshing the list. This maintains a single source of truth and allows Paging to be aware of the changes you've made.
For performance, you can cache your data into a middle DB / in-memory layer, and load items from network via RemoteMediator. If you do this (which you should if you are concerned about performance), the reload becomes quite trivial. See: https://developer.android.com/topic/libraries/architecture/paging/v3-network-db
If you are interested in updating a specific page, you can follow this FR: https://issuetracker.google.com/160232968.
To be clear, you MUST go through the invalidate loop to update the items loaded by Paging. Not doing it this way is currently completely unsupported. It is the only way to make Paging aware of the changes you've made.
The problem comes when recycler uses Androidx paging library.
I have implemented drag and swipe to remove, but when user removes some item from list and next User scrolls down and next scroll up deleted items appear again.
How could I remove item from items source? is it possible?
Do I need always call to backend -> remove -> update list?
I have created a wrapper object to manage deleted items, so when user removes any item I mark into the wrapper object deleted=true so when bind function is called I set visibility=GONE if this flag is true an vice-verse.
The only way to remove items in Paging at the moment is to go through an invalidate loop where you essentially ask Paging to reload from last scroll position.
If you are loading directly from network you might be interested in doing this in a layered way with a local cache in DB to make this less expensive via the RemoteMediator API.
For self-updating pages, there is an open bug you may follow for that feature request here: https://issuetracker.google.com/issues/160232968
I am using the Paging library from Android Jetpack to have a paged loading behavior in my RecyclerView. I'm loading directly from network so I don't have any intermediate in-memory cache or database. Whenever something changes I call invalidate() on DataSource (in my case PositionalDataSource) so that the list is refreshed.
What I need is very simple thing - once I call invalidate() the recycler view is fully cleaned up and shows empty data. I need the recycler view to keep the old data and update normally once the new data comes in. In most of the cases the update might be very small, like a button color change in couple of rows, it looks ugly when the RecyclerView shows empty content for couple of seconds while I'm loading data from backend.
Can this somehow be done or is there a conceptual limitation of the current Paging library architecture forcing me to implement my own caching?
calling notifyDataSetChanged instead of invalidate may help as a simple solution.
I implemented https://stackoverflow.com/a/24882417 but this question is very old. My list, when the items load, gets shifted to the top, and I have to scroll all the way to the bottom again.
I think there's a better way of doing lists that automatially update when you reach the end, so I'm asking it in 2020.
The Android Jetpack Paging library is the current recommendation here.
You should use a RecyclerView instead of a ListView, and then you can create an adapter that subclasses PagedListAdapter. From there, you can created PagedList instances from your data source, and submit them to your adapter via submitList. You can find more information and a detailed walkthrough in the documentation for the Paging library.
In my Android app i'm showing data in a RecyclerView using Room and the Paging library.
My implementation is quite similar to the example in the AsyncPagedListDiffer docs.
The flow is the following:
Data is changed in the database
A corresponding Observer passes the changes to the Adapter:
myLiveData.observe(viewLifecycleOwner, Observer {
myAdapter.submitList(it)
})
The AsyncPagedListDiffer calculates the diff and updates the list accordingly
My problem is the performance hit of step 3.
Even if i insert just one single item to the top of the list, the differ have to check all of the items (which is quite inefficient, especially with larger datasets), whereas a simple notifyItemInserted(0) call would be sufficient.
Is there a way around this behavior?
For example, can i tell the differ that it doesn't have to check all of the items? Or any other solutions to this?
I'd really appreciate any advice.