279 votes

Android : je suis incapable d’avoir des ViewPager WRAP_CONTENT

J’ai installé un ViewPager simple qui a une ImageView avec une hauteur de 200dp sur chaque page.

Voici mon téléavertisseur :

Malgré la hauteur définie comme wrap_content, le pagineur remplit toujours l’écran même si l’imageview est 200dp seule. J’ai essayé de remplacer la hauteur du pagineur avec « 200 », mais ça me donne des résultats différents avec plusieurs résolutions. Je ne parviens pas à ajouter des « dp » à cette valeur. Comment puis-je ajouter 200dp à disposition du pager ?

435voto

La substitution d’onMeasure de votre `` comme suit le fera obtenir la hauteur de l’enfant plus grand, le véhicule a actuellement.

112voto

cybergen Points 678

L'autre, plus générique solution est d'obtenir de l' wrap_content simplement.

Je l'ai étendu ViewPager pour remplacer onMeasure(). La hauteur est wraped autour de la première vue enfant. Cela pourrait conduire à des résultats inattendus si l'enfant vues ne sont pas exactement la même hauteur. Pour que la classe peut être facilement étendu à disons animer à la taille de la vue en cours/page. Mais je n'ai pas besoin de ça.

Vous pouvez utiliser cette ViewPager dans yout XML mises en page tout comme l'original ViewPager:

<view
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    class="de.cybergen.ui.layout.WrapContentHeightViewPager"
    android:id="@+id/wrapContentHeightViewPager"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"/>

Avantage: Cette approche permet à l'aide de la ViewPager dans n'importe quelle forme, y compris RelativeLayout superposer à d'autres éléments de l'interface utilisateur.

Un inconvénient demeure: Si vous souhaitez utiliser les marges, vous devez créer deux imbriqués mises en page et de donner à l'intérieur de la marge.

Voici le code:

public class WrapContentHeightViewPager extends ViewPager {

    /**
     * Constructor
     *
     * @param context the context
     */
    public WrapContentHeightViewPager(Context context) {
        super(context);
    }

    /**
     * Constructor
     *
     * @param context the context
     * @param attrs the attribute set
     */
    public WrapContentHeightViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

        // find the first child view
        View view = getChildAt(0);
        if (view != null) {
            // measure the first child view with the specified measure spec
            view.measure(widthMeasureSpec, heightMeasureSpec);
        }

        setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, view));
    }

    /**
     * Determines the height of this view
     *
     * @param measureSpec A measureSpec packed into an int
     * @param view the base view with already measured height
     *
     * @return The height of the view, honoring constraints from measureSpec
     */
    private int measureHeight(int measureSpec, View view) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            // set the height from the base view if available
            if (view != null) {
                result = view.getMeasuredHeight();
            }
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

}

38voto

Jave Points 14930

Je viens de répondre à une question très semblable à ce sujet, et arrivé à trouver ce lors de la recherche d'un lien pour sauvegarder mes revendications, si vous avez de la chance :)

Mon autre réponse:
Le ViewPager ne prend pas en charge wrap_content que (généralement) n'ont jamais tous ses enfants chargés en même temps, et ne peut donc pas obtenir une taille appropriée (l'option serait d'avoir un pager qui change de taille à chaque fois que vous avez mis en page).

Vous pouvez cependant les dimensions précises (par exemple, 150dp) et match_parent fonctionne aussi bien.
Vous pouvez également modifier les dimensions de manière dynamique à partir de votre code en changeant l' height-attribut dans ses LayoutParams.

Pour vos besoins , vous pouvez créer le ViewPager dans son propre fichier xml, avec la layout_height ensemble de 200dp, et puis dans votre code, plutôt que de créer un nouveau ViewPager à partir de zéro, vous pouvez gonfler que fichier xml:

LayoutInflater inflater = context.getLayoutInflater();
inflater.inflate(R.layout.viewpagerxml, layout, true);

17voto

Idan Points 542

Je suis tombé juste sur la même question. J’ai eu une ViewPager et j’ai voulu afficher une annonce sur le bouton de celui-ci. La solution que j’ai trouvé était d’obtenir le pagineur dans une RelativeView et affectez layout_above c' est l’id de la vue que je veux voir au-dessous de lui. Cela a fonctionné pour moi.

Voici ma mise en page XML :

8voto

Blackhex Points 763

Une autre solution est de mettre à jour ViewPager la hauteur en fonction de la page en cours de hauteur dans ses PagerAdapter. En supposant que vous êtes à la création de votre ViewPager pages de cette façon:

@Override
public Object instantiateItem(ViewGroup container, int position) {
  PageInfo item = mPages.get(position);
  item.mImageView = new CustomImageView(container.getContext());
  item.mImageView.setImageDrawable(item.mDrawable);
  container.addView(item.mImageView, 0);
  return item;
}

mPages est liste interne de l' PageInfo des structures ajoutées dynamiquement à l' PagerAdapter et CustomImageView est juste régulières ImageView avec surchargée onMeasure() méthode qui définit sa hauteur selon la largeur spécifiée et la garde d'image ratio d'aspect.

Vous pouvez forcer l' ViewPager de la hauteur en setPrimaryItem() méthode:

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
  super.setPrimaryItem(container, position, object);

  PageInfo item = (PageInfo) object;
  ViewPager pager = (ViewPager) container;
  int width = item.mImageView.getMeasuredWidth();
  int height = item.mImageView.getMeasuredHeight();
  pager.setLayoutParams(new FrameLayout.LayoutParams(width, Math.max(height, 1)));
}

Remarque l' Math.max(height, 1). Que des correctifs de bug gênant qu' ViewPager ne met pas à jour page affichée à l'écran (il montre la vierge), lors de la précédente page a la hauteur nulle (j'. e. null drawable dans l' CustomImageView), chaque impair glisser d'avant en arrière entre deux pages.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X