I'm building an infinite horizontal scroll list by using a Recycler view. 1-2 children can be visible on the screen at all times (since their width is more than the screen viewport and so we'll never have more than 2 children visible).
Initial state:
While the user is scrolling (they can scroll BOTH forward and backwards - but for the shake of this example, let's assume they are scrolling BACKWARDS), I'm fetching more data, and I'm prepending them to my adapter data.
I'm then calling notifyItemRangeInserted
- so far so good.
After prepend:
Clipping time:
At the same time I add all those children I check wether we now end up with more than MAX_DATASOURCE_CNT
items in the datasource.
Let's assume that MAX_DATASOURCE_CNT
is 6 for this example.
If we do, I remove the unnecessary extra children from the end of our data source and then call notifyItemRangeRemoved
.
I do that because I don't want to flood the device with unused data. I'm over simplifying the example now, but in fact my view can accumulate thousands of unused data items as the user is scrolling, and I want to trim the opposite end of my datasource on the fly.
The problem:
After the prepend process takes place, if the user scrolls too fast, sometimes onBindViewHolder(RecyclerView.ViewHolder holder, int position)
get's called with position == 0
(also holder.getAdapterPosition() == 0
)
That totally messes up my view as it is as if my view jumped to a totally irrelevant child and shows that one.
Current workaround:
I noticed that if I remove the whole clipping process which is basically these lines of code:
if (itemCountAfterPrepend > MAX_DATASOURCE_CNT) {
int extraItemCnt = itemCountAfterPrepend - MAX_DATASOURCE_CNT;
// remove every extra item from the end of the array
removeRange(MAX_DATASOURCE_CNT, itemCountAfterPrepend);
// and notify our adapter about the removal
notifyItemRangeRemoved(MAX_DATASOURCE_CNT, extraItemCnt);
}
everything works fine. But I really want to trim my data. What can I do?
Thank you