web-dev-qa-db-fra.com

ViewPager wrap_content ne fonctionne pas

j'ai fait un scrollview avec à l'intérieur un viewpager. mais le viewpager ne grandit pas en hauteur. Lorsque le contenu dans le viewpager est trop volumineux, il se trouve à l'intérieur, la table est l'espace qui doit être réduit.

J'ai cherché une solution et trouvé que le problème est le "wrap_content", quand le viewpager est chargé, il n'y a pas de contenu. Ainsi, le viewpager conserve la hauteur de l'écran. Les solutions que j'ai trouvées ne sont pas pour "FragmentPagerAdapter", donc j'ai édité cette question.

Veuillez me diriger dans la bonne direction.

Greathings christophe VD

La disposition principale est la suivante: l’horaire en bas est l’un des problèmes:
 enter image description here
Il faut plus comme ça:
 enter image description here

fragmentPagerAdapter est:

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();
        }
    }

}


Et la classe du 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;
    }

}

L'activité:

<?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>

Le 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>
27
user3142817

Vous pouvez personnaliser la ViewPager pour redimensionner la ViewPager à la taille actuelle de la page lors du balayage de page.

Vous pouvez utiliser le code ci-dessous.

 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();
        }
    }

Déclarez-le en xml:

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

Après cet appel, la fonction reMeasureCurrentpage est balayée.

    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) {

                }
            });
53
Abhishek V

J'ai vraiment aimé la réponse de @ abhishek-v, mais j'ai mis à jour: 

  • addPageChangeListener(...) appelé dans notre ViewPager (il n'est pas nécessaire d'appeler reMeasureCurrentPage(...) manuellement à l'extérieur lors du balayage de page)
  • pas besoin de stocker mCurrentPagePosition, car nous pouvons utiliser getCurrentItem()
  • blocage des déchets try/catch

ViewPager ressemble maintenant à:

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);
    }

}
11
repitch

Enfin trouvé une meilleure solution pour WrapContentViewPager!

L'autre solution contient un bug difficile à résoudre, mais je pense que cette solution peut être simplement appliquée dans notre code

Je l'ai trouvé sur ce site https://github.com/akhahaha/burn-Android/blob/master/app/src/main/Java/com/ucla/burn/Android/WrapContentViewPager.Java

Voici le 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);
        }
    }
10
Juggle Jack

Sur Android 8.0, vous devez appeler un autre requestLayout pour le faire fonctionner:

....@Abhishek's answer

sharePager.post(new Runnable() {
            @Override
            public void run() {
                sharePager.requestLayout();
            }
        });
1
legendmohe

dans mon cas, j'ai créé imageslider avec viewpager. la valeur initiale de l'enfant est nulle également à la fin de l'index, la valeur de l'enfant est nulle. donc, j'ai fait quelques mises à jour pour repitch answer, car il ne gérait pas (child==null)

ViewPager ressemble maintenant à:

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);
    }

}

de plus, vous pouvez ajouter la hauteur que vous voulez, si le dernier élément du visualiseur se limite à circlepageindicator, comme ceci: int h = child2.getMeasuredHeight()+50; 

1
Hammad Syarif

Si ces réponses ne permettent toujours pas de résoudre le problème, je peux fournir un autre choix . Dans le fichier Java PagerAdapter, vous pouvez mesurer la hauteur page manuellement et définir le LayoutParams.height du conteneur dans la méthode instantiateItem. Comme ça:

@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;
}
0
KFJK