I'm making a TO-DO list app and I want to have that fancy list, where tasks are grouped under a header with date (similar to what Splen-DO has). I am using Android Paging library (with RecyclerView) with Room (as Data storage). For the headers, I'm using RecyclerView's view types and for adding the headers into the list I'm using custom Datasource, that wraps the Room's datasource and instead of returning a Task Object, it returns an object that can be either Task or a Header.
It works like this:
- Paging Library asks my datasource to load items, it calculates the offset caused by the headers, loads data from the database and adds the headers into the list of Tasks (and Headers) and returns it.
- Paging library uses my Adapter to Create ViewHolders and views and displays the result
Everything works fine until I make a change to the database. Items shift in the RecyclerView for no reason, some duplicate and there are some empty placeholders on the begging of the RecyclerView. So far I've been trying to solve the "empty placeholders on the begging" issue.
I've checked my datasource first, it returns right data with no offset. Then I checked the adapter. The getItem() method returns all item with offset and some null items on the beginning. As I started to dig deeper, I found that it is caused by some mLoadingNullCount in PagedStorage which I have no idea what it is used for, because it has no documentation.
Screenshots
The list working right
The list working right
The empty placeholders on top of list, after I made a change to the list
Empty placeholders
List bugs (gif)
Bugged list
Some Code
Please ignore some variable and class name, I use some Czech words so that they do not mess up with some system classes.
Ukol = Task
Adapter:UkolListAdapter.java
Datasource:MyDatasource.java
Fragment:UkolListFragment.java
Notes
If you need some more code or explanation just leave a comment, I will add it for you.
Edit
I found a mistake. The datasource from Room database may not give you list staritng where you requested, but where it wants, on loadInitial()
and gives you the index (where the returned list is starting) in the int position
parametr of onResult()
. So I was returning wrong data on loadInitial()
. So I added some algorythms, that calculate what data I am actually returning in LoadInitial()
. I didn't fix the problem.