How to scroll recyclerView programmatically?
Asked Answered
G

5

24

I have a horizontal recyclerView, When I first open the activity I want to make all the items in recyclerview scroll to the bottom (to the right in this case) and back to the top (to the left). Kinda like an animation. Scroll behavior should be visible to the user.

I tried to do it like:

Animation slideRight = AnimationUtils.loadAnimation(this, R.anim.slide_right);
        Animation slideLeft = AnimationUtils.loadAnimation(this, R.anim.slide_left);
        slideRight.setDuration(1000);
        slideLeft.setDuration(1000);
        slideRight.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                recyclerView.startAnimation(slideLeft);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        recyclerView.startAnimation(slideRight);

anim slide left:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false" >

    <translate
        android:duration="200"
        android:fromXDelta="-100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />

</set>

anim slide right:

<translate
    android:duration="200"
    android:fromXDelta="100%"
    android:fromYDelta="0%"
    android:toXDelta="0%"
    android:toYDelta="0%" />

it works however it just slides the recyclerview as a whole, I just want to scroll(slide) the items. How can I do this?

Gadwall answered 19/2, 2018 at 9:10 Comment(3)
with the constant speed? if so, when you have hundreds items it will take forever, if not (constant time) the items will be shown for fraction of second...Arabia
I have only 10 items, this value is not going to changeGadwall
so use smoothScrollToPosition()Arabia
M
48

You can use scrollToPosition()

recyclerView.post(new Runnable() {
    @Override
    public void run() {
        recyclerView.scrollToPosition(adapter.getItemCount() - 1);
        // Here adapter.getItemCount()== child count
    }
});

or smoothScrollToPosition()

recyclerView.post(new Runnable() {
    @Override
    public void run() {
        recyclerView.smoothScrollToPosition(adapter.getItemCount()- 1);
    }
});

To move up again, you need to call the above method with index 0. But first, you need to make sure that the RecyclerView is scrolled to last. So, put a ScrollListener on RecyclerView to make sure the last item is visible.

Modernity answered 19/2, 2018 at 9:15 Comment(10)
I think the OP wanted a showcase scroll, kinda like scrolling through to the end and back again.Emmaline
Yeah i guess so . Thx for Clearing . I got it wrong at first place .Modernity
@Emmaline exactly what I meantGadwall
recyclerView.postDelayed(() -> recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount() - 1), 1000); recyclerView.postDelayed(() -> recyclerView.smoothScrollToPosition(0),500); is an option but it scrools to fast thoughGadwall
btw if you use scrollListener, users cant scroll to bottom, everytime they do that it goes back to topGadwall
a boolean can work in this case for first time. Also in case of SHOWcase there must be an overlay view so that user can not interact with list while its scrolling .Modernity
Whats your case ? If its not the same then you can post a new question .Modernity
works, but what happens when getItemCount() is 0?Bedder
Well you should check for it first . if getItemCount() is 0 then index will be -1 that will probably throw an IllegalArgumentException .Modernity
Why is it necessary to run a Runnable instead of calling scrollToPosition() directly?Carbonous
S
4

Use this..

 int top = 0;
 recyclerView.smoothScrollToPosition(top); // for top

 int bottom = recyclerView.getAdapter().getItemCount()-1;
 recyclerView.smoothScrollToPosition(bottom);
Stonybroke answered 19/2, 2018 at 9:15 Comment(0)
S
2

if you need scroll item of recyclerview to CENTER of screen when for ex. expand your item - use this way:

in app/build.gradle - insert:

 implementation 'com.andkulikov:transitionseverywhere:1.7.4'

when hadle click in onBindViewHolder of adapter - insert:

AutoTransition transitionPort = new AutoTransition();
                transitionPort.setDuration(100);
                transitionPort.addListener(new Transition.TransitionListener() {
                    @Override
                    public void onTransitionStart(@NonNull Transition transition) {
                        recyclerView.setEnabled(false);
                        recyclerView.setClickable(false);
                    }

                    @Override
                    public void onTransitionEnd(@NonNull Transition transition) {
                        recyclerView.post(() -> recyclerView.smoothScrollToPosition(position));
                        recyclerView.setEnabled(true);
                        recyclerView.setClickable(true);
                    }

                    @Override
                    public void onTransitionCancel(@NonNull Transition transition) {
                        recyclerView.setEnabled(true);
                        recyclerView.setClickable(true);
                    }

                    @Override
                    public void onTransitionPause(@NonNull Transition transition) {

                    }

                    @Override
                    public void onTransitionResume(@NonNull Transition transition) {

                    }
                });
                TransitionManager.beginDelayedTransition(recyclerView, transitionPort);
Sulla answered 31/7, 2019 at 10:51 Comment(0)
L
1

Not working after trying other things?

This excellent piece of code worked for me

private void scrollToBottom(final RecyclerView recyclerView) {
    // scroll to last item to get the view of last item
    final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
    final RecyclerView.Adapter adapter = recyclerView.getAdapter();
    final int lastItemPosition = adapter.getItemCount() - 1;

    layoutManager.scrollToPositionWithOffset(lastItemPosition, 0);
    recyclerView.post(new Runnable() {
        @Override
        public void run() {
            // then scroll to specific offset
            View target = layoutManager.findViewByPosition(lastItemPosition);
            if (target != null) {
                int offset = recyclerView.getMeasuredHeight() - target.getMeasuredHeight();
                layoutManager.scrollToPositionWithOffset(lastItemPosition, offset);
            }
        }
    });
}

You can modifyline, if you want to jump to some other listitem & not last

final int lastItemPosition = adapter.getItemCount() - 1;

Source

Laggard answered 30/5, 2020 at 11:14 Comment(0)
L
0

If anyone looking for this solution in 2023, here is a way to achieve the scroll to a certain index in an activity using coroutines. Reason for the not working properly without applying sufficient delay, that both operations of updating list to adapter and scrolling of Recycler view will be in parallel so it won't guarantee scrolling happens after submitting the list to the adapter.

 adapter.submitList(uiState.yourList) // using ListAdapter for better perfomance
 lifecycleScope.launch {
    delay(500)
    binding.rvNews.smoothScrollToPosition(INDEX_VALUE) // scrolls to the top for Index value 0
}
Littrell answered 26/9, 2023 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.