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

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);
}

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