To not let question without answer in case someone else has the same problem
With Support library 24.2 Diffutils was released as a helpful class to calculate differences between two sets of items.
Sample code could look something like this (creating two lists and with press of button swapping the items in adapter). DiffUtil.DiffResult will handle all notify calls.
final List<RecyclerObject> list = new ArrayList<>(); list.add(new RecyclerObject("A")); list.add(new RecyclerObject("B")); list.add(new RecyclerObject("C")); list.add(new RecyclerObject("D")); final TestAdapter adapter = new TestAdapter(list); recycler.setAdapter(adapter); final List<RecyclerObject> newList = new ArrayList<>(); newList.add(new RecyclerObject("A")); newList.add(new RecyclerObject("E")); final View button = findViewById(R.id.mainButton); button.setOnClickListener(v -> { adapter.setList(newList); DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffCallback(list, newList)); diffResult.dispatchUpdatesTo(adapter); });
Diffcallback is own created class, implementation could look something like this. (unnecessary code removed for better readability)
public class DiffCallback extends DiffUtil.Callback { DiffCallback(final List<RecyclerObject> list, final List<RecyclerObject> newList) { this.list = list; this.newList = newList; } @Override public int getOldListSize() { return list.size(); } @Override public int getNewListSize() { return newList.size(); } @Override public boolean areContentsTheSame(final int oldItemPosition, final int newItemPosition) { return list.get(oldItemPosition).title.equals(newList.get(newItemPosition).title); } }
There is also one less fancy method : If we can guarantee that items backing the adapter are "stable" and same item will always have the same identificator, recycler.adapter allows for setHasStableIds option. With that, even using only notifyDatasetChanged (which normally kills animations) will correctly process them. Requires override of function getItemId()