ViewPager in a NestedScrollView

前端 未结 19 2145
面向向阳花
面向向阳花 2020-11-27 10:08

I need to create an interface like Google Newsstand which is a sort of ViewPager (horizontal scroll) over a collapsing header (vertical scroll). One of my requirements is to

19条回答
  •  星月不相逢
    2020-11-27 10:24

    I had a layout with an app toolbar with NestedScrollView below it, then inside nested toolbar was a LinearLayout, below the LinearLayout was a view pager. Idea was the LinearLayout inside the NestedScrollView was fixed - you could slide left/right between the views of the view pager but this content wouldn't move, horizontally at least. You should still be able to scroll all the content vertically because of the nested scroll view. That was the idea. So I set nested NestedScrollView height to match_parent, fill viewport, then all the child layouts/ViewPager to wrap_content.

    In my head that was right. But it didn't work - ViewPager allowed me to go left/right, but no vertical scrolling, whether the viewpager page content pushed below the bottom of the current screen or not. Turns out it was basically because the ViewPager doesn't respect wrap_content across its various pages.

    I got round this by subclassing the ViewPager to make it change height depending on the current selected item, sort of forcing it to behave like layout_height="wrap_content":

    public class ContentWrappingViewPager extends ViewPager {
    
        public ContentWrappingViewPager(Context context) {
            super(context);
        }
    
        public ContentWrappingViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            int height = 0;
            if (getChildCount() > getCurrentItem()) {
                View child = getChildAt(getCurrentItem());
                child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                int h = child.getMeasuredHeight();
                if(h > height) height = h;
            }
    
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    

    Solution was inspired by this answer. Worked for me!

提交回复
热议问题