I am using a RecyclerView
with ListAdapter (which uses AsyncListDiffer to calculate and animate changes when list is replaced).
The problem is that if I submit()
some list, then re-order that list, and submit()
again, nothing happens.
How do I force ListAdapter
to evaluate this new list, even though it is "the same" (but order has changed)?
New findings:
I checked source code of submitList() and in the beggining there is a check:
public void submitList(@Nullable final List<T> newList) {
final int runGeneration = ++this.mMaxScheduledGeneration;
if (newList != this.mList) {
I think this is the problem. But how to get past it? I mean, surely the developers thought about submiting a different ordered list?
Instead of
submitList(mySameOldListThatIModified)
You have to submit a new list like this:
ArrayList newList = new ArrayList(oldList);
newList.add(somethingNew); // Or sort or do whatever you want
submitList(newList);
It's kind of a problem with the API. We would expect ListAdapter to keep a copy of the list, but it doesn't, probably for memory reasons. When you change your old list, you are actually changing the same list that ListAdapter has stored. When ListAdapter checks if (newList != this.mList)
both newList
and mList
are referring to the same list instance, so no matter what you have changed on that list, it will equal itself, and ignore your update.
In kotlin you can create a new list via:
val newList = oldList.toMutableList() // Unintuitive way to copy a list
newList[0] = newList[0].copy(isFavourite = false) // Do whatever modifications you want
submitList(newList)
Note that you cannot do this:
newList.first().isFavourite = false
because that will also change the first item in your old list, and again ListAdapter
won't see a difference between the first item in your old list and the first item in your new list. I would recommend that all items in your list have val
properties exclusively, to avoid this problem.