Cheok Yan Cheng
Cheok Yan Cheng

Reputation: 42670

RecyclerView scroll to desired position without animation

Previously, when I want to scroll a ListView to a desired position, I will use

listView.setSelection(row);

The ListView will be scrolled without any animation - Android List View set default position without animation

Now, I want to achieve the same effect on RecyclerView. I try to perform

((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(row, 0);

However, there is scrolling animation, which I would like to avoid.

Is there any way I can perform programmatically scrolling, without animation?

This is the animation I meant - https://youtu.be/OKsUKwBLoks

Note, I had already tried the following ways. All of them do generate animation.

Upvotes: 20

Views: 14719

Answers (5)

ucMax
ucMax

Reputation: 5428

As @nyconing said in the comments, this behavior is caused by the default ItemAnimator attached to the recycler view. Just remove it!

    recyclerView.setItemAnimator(null);

Upvotes: 1

ZeGerm4n
ZeGerm4n

Reputation: 301

I know I'm a little late with this answer but it may help someone else. Try following (at least I could not see any animation when using it):

Kotlin:

    //-- Immediately jump to the position in RecyclerView without delay or animation.
    mRecyclerView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            mRecyclerView.scrollToPosition(position)
            mRecyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this)
        }
    })

Java:

mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mRecyclerView.scrollToPosition(position);
            mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
});

Upvotes: 16

nyconing
nyconing

Reputation: 1136

This can be re-produced easily when you calling notifyItemInserted() with scrollToPosition() at same time.

Animation is caused by DefaultItemAnimator in RecyclerView default item animator class.

I found Youtube video that re-produced problem by other person.

And I has solution too:

  • First, scroll to last position with scrollToPosition().
  • Second, wait a little bit to let layout manager to finish scrolling.
  • Third, add item into your adapter data set.
  • Fourth, calling notifyItemInserted() and scrollToPosition() now.

I have code example but written in , but it does same to with lambda expression. If you need accessing RecyclerView inside Adapter, you might want to look into Adapter.onAttachedToRecyclerView().

if (Adapter.ListData.Count > 2) Adapter.RecyclerView.ScrollToPosition(Adapter.ListData.Count - 1);
Adapter.RecyclerView.PostDelayed(() =>
{
    Adapter.ListData.Add(new ItemSimplyfiedAdapter.Standard
    {
       //Some new item inserting into data set.
    });
    Adapter.NotifyItemInserted(Adapter.ListData.Count - 1);
    Adapter.RecyclerView?.ScrollToPosition(Adapter.ListData.Count - 1);
}, 100);

Upvotes: 1

user5647095
user5647095

Reputation:

You can scroll without animation with:

recyclerView.scrollToPosition(position)

Upvotes: 2

Context
Context

Reputation: 1883

Add this line in your layout.xml

android:overScrollMode="never"

EDIT:

Another way to scroll recycleview

recyclerView.smoothScrollToPosition(position);

Upvotes: 2

Related Questions