Search code examples
androidandroid-recyclerviewsmooth-scrollinglinearlayoutmanager

LinearLayoutManager smooth scroll jumps to wrong position


I'm am trying to make a layout similar to how Instagram's filter layout works. Basically when you select a filter it will scroll to the item you selected + 1 showing you that there are more filters.

I currently am trying to build a custom LinearLayoutManager for my horizontal RecyclerView here:

public class LinearLayoutSnapManager extends LinearLayoutManager {
    private int mCurrentPos = 0;

    public LinearLayoutSnapManager(Context context) {
        super(context);
    }

    public LinearLayoutSnapManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public LinearLayoutSnapManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

    }


    public void snap(RecyclerView rv, int position) {
        if (mCurrentPos == position) {
            // No move
            return;
        }

        boolean goingRight = true;
        if (position < mCurrentPos) {
            goingRight = false;
        }
        mCurrentPos = position;
        smoothScrollToPosition(rv, new RecyclerView.State(), goingRight ? getScrollRightPos(): getScrollLeftPos());
    }

    private int getScrollLeftPos() {
        int newPos = mCurrentPos - 1;
        return (newPos > 0) ? newPos : 0;
    }

    private int getScrollRightPos() {
        return mCurrentPos + 1;
    }
}

Scrolling left works just as intended but when I'm scrolling right it seems to just jump to the end of the list versus the newItem + 1 and I can't figure out why it happens.

enter image description here


Solution

  • I was calling my snap method in the interface callback from the onclicklistener in my horizontal list. Before the interface was getting called I was setting the selected item and then notifying the view had changed in order update the current state. This was causing all the issues with the layoutmanager returning the bad indexes.

    I discovered this once I made an empty project and tested my logic. To my surprise with worked fine which allowed me to track down the real issue.

    Once I moved the snaplogic before all my view logic everything worked as intended with no change to the code I posted.

    Hope this can help someone in the future.