Search code examples
androidandroid-recyclerviewonscrolllistener

how to know the previous and new positions?


I have a recyclerview with horizontal layout and only one view is visible at a time:

mRecyclerView = findViewById(R.id.rvmain);
mRecyclerView.setOnFlingListener(null);
final SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(mRecyclerView);
mLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new MainActivityRVAdapter(postsModels,MainActivity.this);
mRecyclerView.setAdapter(mAdapter);

using onScrolllistener, everytime I scroll I want to know the starting position and end position. how can know that

i know it will be something to know the newposition:

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        // get newstate position
        if(newState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
            View centerView = snapHelper.findSnapView(mLayoutManager);
            if(centerView != null){
                int pos = mLayoutManager.getPosition(centerView);
                Log.e("Snapped Item Position:",""+pos);
            }
        }
    }

how to know the position before scrolling started

then I want to compare both and do something, where should I use that code.

I tried as per the solution mentioned:

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);


    if(count == 0) {
        View centerView = snapHelper.findSnapView(mLayoutManager);
        if(centerView != null){
            initial_position = mLayoutManager.getPosition(centerView);
            //initial_position2 = ((LinearLayoutManager)mRecyclerView.getLayoutManager()).findFirstVisibleItemPosition();
            Log.e("Initial Item Position:",""+initial_position);
            //Log.e("Initial Item Position2:",""+initial_position2);
        }
    }

    count ++;

    // get newstate position
    if(newState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
        View centerView = snapHelper.findSnapView(mLayoutManager);
        if(centerView != null){
            int pos = mLayoutManager.getPosition(centerView);

            count = 0; // in idle state clear the count again
            Log.e("Snapped Item Position:",""+pos);
        }
    }
}

The result i get is:

E/Initial Item Position:: 0
E/Snapped Item Position:: 1

E/Initial Item Position:: 1
E/Snapped Item Position:: 1

E/Initial Item Position:: 1
E/Snapped Item Position:: 1

E/Initial Item Position:: 1
E/Snapped Item Position:: 1

The final value of the initial position is not same as the one at the beginning of the scroll

And it returns multiple times positions. I don't want to check the difference between final and initial positions for all the multiple positions. I just want to check at the end.

Solution for my problem

As I saw even if i scroll one poistion the onScrollListener runs 4 times. I found there is no way to control how many times it runs, but i was looking to do something only when it runs first time. I am looking to run a code if pos != initial_position. which i saw is true only for the first time and later its false.

My problem was whenever i land at any view which is not same as the previous view i want to reset the font.

the final code:

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        if(count == 0) {
            View centerView = snapHelper.findSnapView(mLayoutManager);
            if(centerView != null){
                initial_position = mLayoutManager.getPosition(centerView);
                //initial_position2 = ((LinearLayoutManager)mRecyclerView.getLayoutManager()).findFirstVisibleItemPosition();
                Log.e("Initial Item Position:",""+initial_position);
                //Log.e("Initial Item Position2:",""+initial_position2);
            }
            count ++;
        }



        // get newstate position
        if(newState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
            View centerView = snapHelper.findSnapView(mLayoutManager);
            if(centerView != null){
                int pos = mLayoutManager.getPosition(centerView);

                if(pos != initial_position ){
                    TextView textView2 =  (TextView) centerView.findViewById(R.id.postsmodel_description);
                    if(textsize == 0){
                        textsize = textView2.getTextSize();
                    }
                    textView2.setTextSize(pixelsToSp(textsize));
                }
                count = 0; // in idle state clear the count again
                Log.e("Snapped Item Position:",""+pos);
            }
        }


    }

Solution

  • int count = 0; //field variable
    int initial_position;  
    
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    
        if(count == 0) {
           initial_position = mLayoutManager.findFirstVisibleItemPosition();
       }
    
        count ++;
    
        // get newstate position
        if(newState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
            View centerView = snapHelper.findSnapView(mLayoutManager);
            if(centerView != null){
                int pos = mLayoutManager.getPosition(centerView);
    
                count = 0; // in idle state clear the count again 
                Log.e("Snapped Item Position:",""+pos);
            }
        }
    }
    

    initial_position = starting position

    pos = ending position

    Happy coding :)