Search code examples
androidandroid-recyclerviewkotlinandroid-viewpagerandroid-nestedscrollview

RecyclerView inside viewpager


I try to implement a layout like below image.

in this layout first ViewPager has fix height and second Viewpager contain RecyclerView.

How can connect scroll RecyclerView in Viewpager to NestedScrollView in parent?

I try this: nestedScrollView.isFillViewport = true but RecyclerView scroll from top of Viewpager.

enter image description here


Solution

  • I have faced this issue some time ago. Where you want RecyclerView to be Scrolled by NestedScrollView. And nestedScrollingEnabled will not help you because RecyclerView is inside ViewPager.

    Solution You can customize the ViewPager to resize the ViewPager to it's current page size on page swipe from this answer.

    You can use the following code:

     public class WrapContentViewPager extends ViewPager {
    
            private int mCurrentPagePosition = 0;
    
            public WrapContentViewPager(Context context) {
                super(context);
            }
    
            public WrapContentViewPager(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
    
            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            try {
                 boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;
                 if (wrapHeight) {
                     View child = getChildAt(mCurrentPagePosition);
                     if (child != null) {
                     child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                     int h = child.getMeasuredHeight();
    
                     heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
                    }
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
            public void reMeasureCurrentPage(int position) {
                mCurrentPagePosition = position;
                requestLayout();
            }
        }
    

    Declare it in xml:

        <your.package.name.WrapContentViewPager
                android:id="@+id/view_pager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
        </your.package.name.WrapContentViewPager>
    

    After that call reMeasureCurrentpage function on page swipe.

        final WrapContentViewPager wrapContentViewPager = (WrapContentViewPager) findViewById(R.id.view_pager);
    
        wrapContentViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                    @Override
                    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                    }
    
                    @Override
                    public void onPageSelected(int position) {
                        wrapContentViewPager.reMeasureCurrentPage(wrapContentViewPager.getCurrentItem());
                    }
    
                    @Override
                    public void onPageScrollStateChanged(int state) {
    
                    }
                });
    

    Also set android:nestedScrollingEnabled="false" to your RecyclerView.