Search code examples
androidandroid-layoutandroid-recyclerviewandroid-viewpagerscrollview

Sync scroll of horizontal recylerview with viewpager scroll


i have a view pager with some values, same count for the recycler view abovethe recylerview(Act like a tablayout)

i have achieved the function with snap helper and all working fine only thing i want is i want to sync the scroll of the recyclerview with viewpager scroll, which i cant able to achive.

The below is what i want to achive

But what i am getting is like below

i override the scroll of view page but have no use

 @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

myRecyler..scrollBy(positionOffsetPixels,0);
}

But its making strange behavior i also tried scrollToPositionWithOffset

layoutManagerStart.scrollToPositionWithOffset(position,positionOffsetPixels);

but both failed, i use snap helperso the selected item will be on the first position.

Can any one help me to achieve the effect like the above one.


Solution

  • I also had the same problem as you havent provided proper info am adding the following snippet

    You need to pass the positionoffset of viewpager to the funtion as you said scrollToPositionWithOffset is the correct way but you need to do some calculation before that.

    Check the following code

    protected void scrollToTab(int position, float positionOffset) {
        int scrollOffset = 0;
    
        if (mItemWidth == 1 && yourrecylerview != null) {
            View child = yourrecylerview.getChildAt(0);
            if (child != null) {
                mItemWidth = child.getMeasuredWidth() * 2;
            }
        }
    
        View selectedView = yourlayoutmanager.findViewByPosition(position);
        View nextView = yourlayoutmanager.findViewByPosition(position + 1);
    
        if (nextView != null) {
            if (selectedView != null) {
                int width = yourrecylerview.getMeasuredWidth();
                float sLeft = (position == 0) ? 24 : width / mItemWidth - selectedView.getMeasuredWidth() / mItemWidth; // left edge of selected tab
                float sRight = sLeft + selectedView.getMeasuredWidth(); // right edge of selected tab
                float nLeft = width / mItemWidth - nextView.getMeasuredWidth() / mItemWidth; // left edge of next tab
                float distance = sRight - nLeft; // total distance that is needed to distance to next tab
                float dx = distance * positionOffset;
                scrollOffset = (int) (sLeft - dx);
            } else {
                scrollOffset = (mItemWidth/2) * (-1);
                //mRequestScrollToTab = true;
            }
    
            if (position != 0) {
                // scrollOffset=scrollOffset-10;
            }
    
            mIndicatorPosition = position;
            yourrecylerview.stopScroll();
    
            if ((position != mOldPosition || scrollOffset != mOldScrollOffset)) {
    
                yourlayoutmanager.scrollToPositionWithOffset(position, scrollOffset);
    
            } 
    
        }
        else
        {
            //Sometimes view go null for handling that situvation
            yourrecylerview.scrollToPosition(position);
            yourviewpager.setCurrentItem(position);
        }
    
        mOldPosition = position;
        mOldScrollOffset = scrollOffset;
        mOldPositionOffset=positionOffset;
    
    }
    

    Add the above methord on you addOnPageChangeListener of viewpager

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                         scrollToTab(position, positionOffset);
                           }
    

    I have made a sample which help you if you want further verification RecyclerParallelViewPager go to link to see the solution

    gif

    Hope this will help you