Search code examples
javaandroidandroid-viewpager

Android - Update ViewPager whith child of different heights


I have a ViewPager implemented without fragment (just view). Each page contains a list of elements, but the list hasn't always the same size.

I tried to set the ViewPager dimension with this code (extends ViewPager so I can override this function) :

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        for(int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            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);
    }

The problem is that it set the same height for every page. I need a custom height for each page, depending of the height of the list.

I also tried to use setOnPageChangeListener calling requestLayout() and invalidate() on the ViewPager, but the size remains the same. Maybe I did it wrong...

Here is some code that might be useful :

A part of my PagerAdapter:

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // Inflate a new layout from our resources
            View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_home_pager,
                    container, false);

            mContainerView = (ViewGroup) view.findViewById(R.id.news_container);
            reloadNews(position);

            // Add the newly created View to the ViewPager
            container.addView(view);

            // Return the View
            return view;
        }

A part of my XML layout:

        <ScrollView
            android:id="@+id/news_scrollview"
            android:layout_width="match_parent"
            android:layout_height="fill_parent">

            <com.ViewPagerWithHeight
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white"/>

        </ScrollView>

Thanks of lot for helping me,


Solution

  • I just find out something that do the job.

    I moved the Scrollview inside the pageItem.xml so I can set the page size (for all pages) but still can scroll if the list is long enough. The ViewPager is now inside a FrameLayout with layout_height = fill_parent.

    The page size is fixed, but the scrollview do the trick...

    The ViewPager (inside my fragment) :

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:id="@+id/viewpagercontainer">
    
        <com.ViewPagerWithHeight
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"/>
    
    </FrameLayout>
    

    The "Page item" :

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/news_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:showDividers="middle"
            android:divider="?android:dividerHorizontal" />
    
    </ScrollView>
    

    onMeasure function:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(containerHeight, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    

    How to set the attribute containerHeight (more info here):

    final View pagerContainer = (View) mView.findViewById(R.id.viewpagercontainer);
    pagerContainer.post(new Runnable() {
        @Override
        public void run() {
            mViewPager.setContainerHeight(pagerContainer.getMeasuredHeight());
        }
    });