Search code examples
androidandroid-recyclerviewnotifyitemchanged

android RecyclerView not following finger when scrolling if items dynamically expand on notifyItemChanged() calls


I use notifyItemChanged() to update items partially, when images are ready, they will show up in the item.

please view my screen recording here As you can see, when scrolling down, the items above expand dynamically and push the items below off the lower border of the screen.

How can I solve this?


Solution

  • After digging into the source code of RecyclerView for a long time, I have found that there is a concept called "anchor", when the RecyclerView is animating, it will try to keep the "anchor" at the same place before and after the animation.

    The "anchor" is determined by some algorithm, usually the first visible child item. This explains why the expansion of the upper children will push the lower children off the lower bound of screen, as the upper visible part of the RecyclerView has been "pinned" by the anchor.

    So here is an opposite solution: set the anchor to the last visible child item, and then the expansion direction of child items will go up.

    The most easy way to set the anchor is to set the focus, the focused child item takes priority when the RecyclerView tries to find an "anchor" child.

    One intuitive solution may be to set the focus to the first visible child when RV scrolls up and set the focus to the last visible child when RV scrolls down. This could be done by using a scroll listener combinded with findFirstVisibleItemPosition(), findLastVisibleItemPosition() and requestFocus().