33

I made a ScrollView containing a ViewPager, but the ViewPager does not grow in height. When the content inside the ViewPager is too big, it get 'pucht'(?) inside, the table is the space that shrinks.

I have search for a solution and found that the problem is the wrap_content, when the ViewPager is loaded there is no content. So the ViewPager keeps the screen height. The solutions that I found are not for FragmentPagerAdapter, so i have edit this question.

Please point me in the right direction.

Greetings, Christophe VD.

The main layout is this, the timetable on the bottom is one of the problems:
enter image description here
It needs more like this:
enter image description here

The FragmentPagerAdapter is:

import android.content.Context;
import android.graphics.pdf.PdfDocument;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class film_tabs_adapter extends FragmentPagerAdapter {
    private final String[] TITLES = { "Info", "Comment", "Cast", "Muziek"};
    String[] Film_Data;

    public film_tabs_adapter(FragmentManager fm, String[] Film_Data_in) {
        super(fm);
        Film_Data = Film_Data_in;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return TITLES[position];
    }


    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment =null;
        Bundle bundle = new Bundle();
        bundle.putStringArray("Film_Data", Film_Data);
        switch(position) {
            case 0:
                //return new film_info();
                fragment = new film_info();
                fragment.setArguments(bundle);
                return fragment;
            case 1:
                return new film_coment();
            case 2:
                return new film_cast();
            case 3:
                return new film_sound();
            default:
                return new film_info();
        }
    }

}


And the class of the Fragment:

    import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class film_info extends Fragment {
    TextView label_locatie;
    ...
    TableLayout TimeTabel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_film_info, container, false); // layout (activity_film_info) openen
        Context context = inflater.getContext();
        DatabaseVerwerker DB = new DatabaseVerwerker(context);
        String[] Film_Data =  getArguments().getStringArray("Film_Data");
        ...
        return view;
    }

}

The Activity:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fillViewport="true"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:id="@+id/header">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="120dp">

                <ProgressBar
                    style="?android:attr/progressBarStyleHorizontal"
                    android:progressDrawable="@drawable/redprogressbar"
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/DownloadCover"
                    android:layout_gravity="top" />

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/FilmCover"
                    android:src="@drawable/cover"
                    android:adjustViewBounds="true"
                    android:padding="-5dp"
                    android:scaleType="centerCrop" />

            </FrameLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="left|right|top"
                android:paddingLeft="7dp">

                <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TableRow
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent">

                        <ImageView
                            android:layout_width="82dp"
                            android:layout_height="120dp"
                            android:id="@+id/FilmPoster"
                            android:src="@drawable/poster_x"
                            android:adjustViewBounds="true"
                            android:layout_gravity="bottom|left" />
                    </TableRow>

                    <TableRow
                        android:layout_width="match_parent"
                        android:layout_height="match_parent">

                        <TextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="New Text"
                            android:id="@+id/FilmTitel"
                            android:textStyle="bold"
                            android:gravity="center_horizontal"
                            android:layout_marginTop="120dp" />
                    </TableRow>
                </LinearLayout>

            </FrameLayout>

        </FrameLayout>

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/body">
            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                tools:context=".MainActivity" >

                <com.astuetz.PagerSlidingTabStrip
                    android:id="@+id/tabs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#dadada"
                    app:pstsShouldExpand="true"
                    app:pstsDividerColor="#EDEDED"
                    app:pstsIndicatorColor="#C3263E"
                    app:pstsDividerPadding="10dp"
                    app:pstsIndicatorHeight="4dp"
                    app:pstsTabPaddingLeftRight="0dp"
                    />

                <android.support.v4.view.ViewPager
                    android:id="@+id/pager"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/tabs"
                    tools:context=".MainActivity"
                    android:soundEffectsEnabled="false" />

            </RelativeLayout>
        </FrameLayout>
    </LinearLayout>
</ScrollView>

The Fragment:

<?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="999dp">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="5dp"
                android:background="#dadada">

                <TableLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:stretchColumns="*">

                    <TableRow
                        android:layout_width="match_parent"
                        android:layout_height="match_parent">

                        <RelativeLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:layout_margin="4dp">

                            <ImageView
                                android:layout_alignParentLeft="true"
                                android:layout_alignParentTop="true"
                                android:layout_width="30dp"
                                android:layout_height="32dp"
                                android:id="@+id/imageView3"
                                android:src="@drawable/icon_locatie"
                                android:layout_margin="2dp" />

                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_alignBottom="@+id/imageView3"
                                android:layout_alignTop="@+id/imageView3"
                                android:layout_toRightOf="@+id/imageView3"
                                android:gravity="center_vertical"
                                android:text="Small Text"
                                android:id="@+id/label_locatie" />

                        </RelativeLayout >

                        <RelativeLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:layout_margin="4dp">

                            <ImageView
                                android:layout_alignParentLeft="true"
                                android:layout_alignParentTop="true"
                                android:layout_width="30dp"
                                android:layout_height="32dp"
                                android:id="@+id/imageView4"
                                android:src="@drawable/icon_speelduur"
                                android:layout_margin="2dp" />

                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_alignBottom="@+id/imageView4"
                                android:layout_alignTop="@+id/imageView4"
                                android:layout_toRightOf="@+id/imageView4"
                                android:gravity="center_vertical"
                                android:text="Small Text"
                                android:id="@+id/label_speelduur" />
                        </RelativeLayout>

                        <RelativeLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:layout_margin="4dp">

                            <ImageView
                                android:layout_alignParentLeft="true"
                                android:layout_alignParentTop="true"
                                android:layout_width="30dp"
                                android:layout_height="32dp"
                                android:id="@+id/imageView5"
                                android:src="@drawable/icon_genre"
                                android:layout_margin="2dp" />

                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_alignBottom="@+id/imageView5"
                                android:layout_alignTop="@+id/imageView5"
                                android:layout_toRightOf="@+id/imageView5"
                                android:gravity="center_vertical"
                                android:text="Small Text"
                                android:id="@+id/label_genre" />
                        </RelativeLayout>
                    </TableRow>

                    <TableRow
                        android:layout_width="match_parent"
                        android:layout_height="match_parent">

                        <RelativeLayout
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:layout_margin="4dp">

                            <ImageView
                                android:layout_alignParentLeft="true"
                                android:layout_alignParentTop="true"
                                android:layout_width="30dp"
                                android:layout_height="32dp"
                                android:id="@+id/imageView6"
                                android:src="@drawable/icon_gesproken"
                                android:layout_margin="2dp" />

                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_alignBottom="@+id/imageView6"
                                android:layout_alignTop="@+id/imageView6"
                                android:layout_toRightOf="@+id/imageView6"
                                android:gravity="center_vertical"
                                android:text="Small Text"
                                android:id="@+id/label_gesproken" />
                        </RelativeLayout>

                        <RelativeLayout
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:layout_margin="4dp">

                            <ImageView
                                android:layout_alignParentLeft="true"
                                android:layout_alignParentTop="true"
                                android:layout_width="30dp"
                                android:layout_height="32dp"
                                android:id="@+id/imageView7"
                                android:src="@drawable/icon_versie"
                                android:layout_margin="2dp" />

                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_alignBottom="@+id/imageView7"
                                android:layout_alignTop="@+id/imageView7"
                                android:layout_toRightOf="@+id/imageView7"
                                android:gravity="center_vertical"
                                android:text="Small Text"
                                android:id="@+id/label_versie" />
                        </RelativeLayout>

                        <RelativeLayout
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_weight="1"
                            android:layout_margin="4dp">

                            <ImageView
                                android:layout_alignParentLeft="true"
                                android:layout_alignParentTop="true"
                                android:layout_width="30dp"
                                android:layout_height="32dp"
                                android:id="@+id/imageView8"
                                android:src="@drawable/icon_ondertiteling"
                                android:layout_margin="2dp" />

                            <TextView
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:layout_alignBottom="@+id/imageView8"
                                android:layout_alignTop="@+id/imageView8"
                                android:layout_toRightOf="@+id/imageView8"
                                android:gravity="center_vertical"
                                android:text="Small Text"
                                android:id="@+id/label_ondertiteling" />
                        </RelativeLayout>
                    </TableRow>

                    <TableRow
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"></TableRow>
                </TableLayout>
            </FrameLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="7dp"
                android:paddingRight="7dp">

                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/label_beschrijving"
                    android:layout_marginBottom="16dp"
                    android:textSize="14sp"
                    android:text="@string/film_FilmBeschrijving" />
            </FrameLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="7dp"
                android:paddingRight="7dp">

                <TableLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/timetabel"
                    android:stretchColumns="*"
                    android:shrinkColumns="*"
                    android:background="@drawable/tb_body" />
            </FrameLayout>
        </LinearLayout>
    </FrameLayout>
ban-geoengineering
  • 18,324
  • 27
  • 171
  • 253
user3142817
  • 787
  • 2
  • 9
  • 15

6 Answers6

69

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

You can use the below 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) {

    }
});
Community
  • 1
  • 1
Abhishek V
  • 12,488
  • 6
  • 51
  • 63
  • where must i add your.package.name.WrapContentViewPager, is that in the activity or in the fragment? i have add the xml layout above – user3142817 Dec 30 '15 at 13:28
  • 1
    Instead of using `android.support.v4.view.ViewPager` use WrapContentViewPager. – Abhishek V Dec 30 '15 at 13:30
  • @user3142817 cast and muziek fragments have listview? – Abhishek V Jan 23 '16 at 05:02
  • it include the same layout with a listview in, i have also give the same code to the activity. it loads, it works, it scrolls but the height is not right. – user3142817 Jan 23 '16 at 12:48
  • 1
    There could be hundreds of rows in list view. It's not good idea to use wrap_content for `ListView`. Either you need to give fixed height for the `ListView` or else you need to use `match_parent`. – Abhishek V Jan 23 '16 at 13:17
  • 1
    `View child = getChildAt(mCurrentPagePosition);` returns `null`. Couldn't figure out the reason. – Farid Mar 11 '17 at 14:36
  • 1
    View child = getChildAt(mCurrentPagePosition); returns null too for me... can someone help me please? – Felipe A. May 16 '17 at 20:12
18

I really liked @abhishek-v answer, but made some upgrades:

  • addPageChangeListener(...) called inside our ViewPager (don't need to call reMeasureCurrentPage(...) manually outside on page swipe)
  • don't need to store mCurrentPagePosition, because we can use getCurrentItem()
  • removed waste try/catch block

ViewPager now looks like:

public class WrapContentViewPager extends ViewPager {

    public WrapContentViewPager(Context context) {
        super(context);
        initPageChangeListener();
    }

    public WrapContentViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPageChangeListener();
    }

    private void initPageChangeListener() {
        addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                requestLayout();
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        View child = getChildAt(getCurrentItem());
        if (child != null) {
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}
repitch
  • 1,858
  • 1
  • 15
  • 34
  • 1
    This solution is not correct completely because when the view pager reaches at the end of fragment list then getChildAt() returns null and the view pager height is set to 0. Its better to have a field to save the height and use it when the view is null. – Rookie Feb 21 '17 at 06:25
  • 2
    I also had the problem of `getChildAt()` returning **null** for my third (and last) fragment. To solve this, rather than calling `viewPager.setOffscreenPageLimit(2)`, I simply replaced `View child = getChildAt(getCurrentItem());` in the above code with **`Fragment childFragment = (Fragment)getAdapter().instantiateItem(this, getCurrentItem()); View child = childFragment.getView();`** (Thanks to this answer to another question: https://stackoverflow.com/a/16512217/1617737 .) – ban-geoengineering May 10 '19 at 12:52
14

Finally found a better solution for WrapContentViewPager!

The other solution contain some bug that hard to be solved, but I think this solution can be simply applied in our code

I found it on this site https://github.com/akhahaha/burn-android/blob/master/app/src/main/java/com/ucla/burn/android/WrapContentViewPager.java

Here is the code

public class WrapContentViewPager extends ViewPager {
        public WrapContentViewPager(Context context) {
            super(context);
        }

        public WrapContentViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @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);
        }
    }
jagel.id
  • 178
  • 1
  • 9
4

in my case, i created imageslider with viewpager. initial value of child is null also at the end of index, value of child is null. so, i made some upgrades for repitch answer, because it didn't handle (child==null)

ViewPager now looks like:

public class WrapContentViewPager extends ViewPager {

    public WrapContentViewPager(Context context) {
        super(context);
        initPageChangeListener();
    }

    public WrapContentViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPageChangeListener();
    }

    private void initPageChangeListener() {
        addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                requestLayout();
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        View child = getChildAt(getCurrentItem());
        if (child != null) {
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        } else {for(int i = 0; i < getChildCount(); i++) {
                View child2 = getChildAt(i);
                child2.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                int h = child2.getMeasuredHeight();
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        }}
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

also, you can add amount of height whatever you want, if the last item of viewpager stick to circlepageindicator, like this : int h = child2.getMeasuredHeight()+50;

icgoogo
  • 401
  • 5
  • 7
2

If these answer still can't fix the problem, I can provide another choice. At the PagerAdapter java file, you can measure the page height manually and set the container's LayoutParams.height in instantiateItem method. Like this:

@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
    View view = generateView(mContext, position);
    view.measure(View.MeasureSpec.makeMeasureSpec(DensityUtil.getScreenWidth(mContext), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    container.getLayoutParams().height = view.getMeasuredHeight();
    container.addView(view);
    return view;
}
KFJK
  • 115
  • 6
1

On Android 8.0, you have to invoke another requestLayout to make it work:

....@Abhishek's answer

sharePager.post(new Runnable() {
            @Override
            public void run() {
                sharePager.requestLayout();
            }
        });
legendmohe
  • 750
  • 7
  • 11