1

I am using a RecyclerView with ListAdapter in which I display 2 types of items: content & placeholder.

In this example the initial list consists of 10 content items and 10 placeholder items, which I then replace with another 10 content items (= always 20 items in total).

Doing this with ListAdapter.submitList(list) works as expected and shows the correct change animations. Like in this GIF:

The Diff working as exptected here

However, when I'm scrolling to a part of the screen where only placeholders are shown then .submitList(list) causes an unwanted scroll, like seen in this GIF:

The Diff triggers a scroll here

My diffing logic: (Should be fine, generally all animations work as expected)

sealed class MyItem {
    data class Content(val text: String) : MyItem()
    data class Placeholder(val text: String) : MyItem()
}

class MyDiffCallback : DiffUtil.ItemCallback<MyItem>() {

    override fun areItemsTheSame(oldItem: MyItem, newItem: MyItem): Boolean =
        oldItem::class == newItem::class && when (oldItem) {
            is MyItem.Content -> oldItem.text == (newItem as MyItem.Content).text
            is MyItem.Placeholder -> oldItem.text == (newItem as MyItem.Placeholder).text
    }

    override fun areContentsTheSame(oldItem: MyItem, newItem: MyItem): Boolean =
        oldItem == newItem
}

What could be wrong? Is this actually working as expected and I'm just missing something?

  • I checked some solutions from other Stackoverflow questions already - mostly about making the RecyclerView and the items not focusable e.g. here - they didn't fix my problem.
  • I also tried to use a normal RecyclerView.Adapter and do the diffing of the new list manually via DiffUtil.calculateDiff(...) - this has the same issue (ListAdapter uses DiffUtil internally after all)
  • I managed to do a workaround by doing adapter.notifyItemRangeChanged(...) on the exact items which changed - this worked and doesn't cause a scroll, but I'm not happy with this workaround and don't want to apply it in all my features
Day
  • 692
  • 1
  • 7
  • 20

0 Answers0