Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android how can I get current positon on recyclerview that user scrolled to item

In my RecyclerView I have some items that user can scroll and see that. Now I want to save this position and scroll that after come back. This below code return 0 always and I can't save that:

recyclerMarketLists.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        recyclerViewCurrentScrolledPosition = recyclerMarketLists.getScrollY();
        Log.e("Y: ", recyclerViewCurrentSceolledPosition + "");
    }
});

the Logcat:

07-07 18:28:30.919 2124-2124/com.sample.presentationproject E/Y:: 0
like image 736
DolDurma Avatar asked Jul 07 '16 14:07

DolDurma


People also ask

Can you display a scrolling list of items in a RecyclerView?

To be able to scroll through a vertical list of items that is longer than the screen, you need to add a vertical scrollbar. Inside RecyclerView , add an android:scrollbars attribute set to vertical .


4 Answers

You are trying to get the info on the wrong object. It is not the RecyclerView nor the Adapter responsibility but the RecyclerView's LayoutManager.

Instead of the generic ViewTreeObserver.OnScrollChangedListener() I would recommend to add instead the RecyclerView.OnScrollListener and use the onScrollStateChanged(RecyclerView recyclerView, int newState) callback which gives you the newState, you should use SCROLL_STATE_IDLE to fetch its position. Meaning:

yourRecyclerView.getLayoutManager().findFirstVisibleItemPosition();

As Rik van Velzen pointed out, you probably need to cast your LayoutManager to a LinearLayoutManager or GridLayoutManager (you have to cast to the correct type you are using) to access these findVisibleXXXX() methods.

On said callback method. Hope I made this clear enough for your, you can find documentation on the classes here:

RecyclerView.OnScrollListener

yigit's (Google) response on visible positions

like image 88
Joaquim Ley Avatar answered Oct 19 '22 03:10

Joaquim Ley


Thanks for solution Joaquim Ley. This helps create recyclerView horizontal pager without using any library.

Init recyclerView

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_vocabulary_list);

    // Set up the recyclerView with the sections adapter.
    mRecyclerView = findViewById(R.id.list);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
    mRecyclerView.setAdapter(new VocabularyListAdapter<>(vocabularyList));
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState == RecyclerView.SCROLL_STATE_IDLE){
                int position = getCurrentItem();
                onPageChanged(position);
            }
        }
    });
    PagerSnapHelper snapHelper = new PagerSnapHelper();
    snapHelper.attachToRecyclerView(mRecyclerView);
}



public boolean hasPreview() {
   return getCurrentItem() > 0;
}

public boolean hasNext() {
    return mRecyclerView.getAdapter() != null &&
            getCurrentItem() < (mRecyclerView.getAdapter().getItemCount()- 1);
}

public void preview() {
    int position = getCurrentItem();
    if (position > 0)
        setCurrentItem(position -1, true);
}

public void next() {
    RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
    if (adapter == null)
        return;

    int position = getCurrentItem();
    int count = adapter.getItemCount();
    if (position < (count -1))
        setCurrentItem(position + 1, true);
}

private int getCurrentItem(){
    return ((LinearLayoutManager)mRecyclerView.getLayoutManager())
            .findFirstVisibleItemPosition();
}

private void setCurrentItem(int position, boolean smooth){
    if (smooth)
        mRecyclerView.smoothScrollToPosition(position);
    else
        mRecyclerView.scrollToPosition(position);
}
like image 32
Vahe Gharibyan Avatar answered Oct 19 '22 01:10

Vahe Gharibyan


This is the extension function in Kotlin:

fun RecyclerView?.getCurrentPosition() : Int {
    return (this?.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
}

You can use it just invoking this function on your RecyclerView:

val position = yourRecyclerView.getCurrentPosition()
like image 14
Mattia Ferigutti Avatar answered Oct 19 '22 01:10

Mattia Ferigutti


Try this in Kotlin:

myRecyclerView.addOnScrollListener(object: RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)
        val offset: Int = myRecyclerView.computeHorizontalScrollOffset()
        if (offset % myRecyclerView.width == 0) {
            val position: Int = offset / myRecyclerView.width
            Log.e("Current position is", position.toString())
        }
    }
})
like image 5
reza_khalafi Avatar answered Oct 19 '22 02:10

reza_khalafi