61 votes

Définition d'une largeur maximale pour un ViewGroup

Comment puis-je définir la largeur maximale d'un ViewGroup ? J'utilise un Theme.Dialog Cependant, cette activité n'est pas très belle lorsqu'elle est redimensionnée sur des écrans plus grands. De plus, elle est un peu légère et je ne veux pas qu'elle occupe tout l'écran.

J'ai essayé cette suggestion en vain. De plus, il n'y a pas android:maxWidth propriété comme certaines vues.

Existe-t-il un moyen de restreindre le Root LinearLayout pour qu'il ne soit (par exemple) que de 640 dip ? Je suis prêt à changer de ViewGroup pour cela.

Des suggestions ?

90voto

Chase Points 7520

Une option, qui est ce que j'ai fait, est d'étendre LinearLayout et de remplacer la fonction onMeasure. Par exemple :

public class BoundedLinearLayout extends LinearLayout {

    private final int mBoundedWidth;

    private final int mBoundedHeight;

    public BoundedLinearLayout(Context context) {
        super(context);
        mBoundedWidth = 0;
        mBoundedHeight = 0;
    }

    public BoundedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BoundedView);
        mBoundedWidth = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_width, 0);
        mBoundedHeight = a.getDimensionPixelSize(R.styleable.BoundedView_bounded_height, 0);
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Adjust width as necessary
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        if(mBoundedWidth > 0 && mBoundedWidth < measuredWidth) {
            int measureMode = MeasureSpec.getMode(widthMeasureSpec);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedWidth, measureMode);
        }
        // Adjust height as necessary
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        if(mBoundedHeight > 0 && mBoundedHeight < measuredHeight) {
            int measureMode = MeasureSpec.getMode(heightMeasureSpec);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mBoundedHeight, measureMode);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

Dans ce cas, vous utilisez la classe personnalisée :

<com.yourpackage.BoundedLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:bounded_width="900dp">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    />
</com.youpackage.BoundedLinearLayout>

Et l'entrée du fichier attr.xml

<declare-styleable name="BoundedView">
    <attr name="bounded_width" format="dimension" />
    <attr name="bounded_height" format="dimension" />
</declare-styleable>

EDIT : Voici le code que j'utilise actuellement. Il n'est pas encore complet mais fonctionne dans la plupart des cas.

33voto

Jonypoins Points 181

Voici un meilleur code pour la réponse de Dori.

En méthode onMeasure Si vous appelez super.onMeasure(widthMeasureSpec, heightMeasureSpec); d'abord dans la méthode, alors la largeur de tous les objets dans le layout ne sera pas modifiée. Car ils ont été initialisés avant que vous ne définissiez la largeur du layout(parent).

public class MaxWidthLinearLayout extends LinearLayout {
    private final int mMaxWidth;

    public MaxWidthLinearLayout(Context context) {
        super(context);
        mMaxWidth = 0;
    }

    public MaxWidthLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout);
        mMaxWidth = a.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE);
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        if (mMaxWidth > 0 && mMaxWidth < measuredWidth) {
            int measureMode = MeasureSpec.getMode(widthMeasureSpec);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, measureMode);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

Et voici un lien pour l'utilisation de l'attr xml :
  http://kevindion.com/2011/01/custom-xml-attributes-for-Android-widgets/

Merci pour cette question et ses réponses. Votre réponse m'a beaucoup aidé, et j'espère qu'elle aidera aussi quelqu'un d'autre à l'avenir.

30voto

Dori Points 4011

Pour compléter la réponse originale de Chase (+1), j'apporterais quelques modifications (décrites ci-dessous).

  1. Je voudrais que la largeur maximale soit définie par un attribut personnalisé (xml sous le code).

  2. J'appellerais super.measure() d'abord et ensuite faire le Math.min(*) comparaison. En utilisant le code de réponses original, nous pouvons rencontrer des problèmes lorsque la taille d'entrée définie dans le fichier MeasureSpec est soit LayoutParams.WRAP_CONTENT ou LayoutParams.FILL_PARENT . Comme ces constantes valides ont des valeurs de -2 et -1 respectivement, l'original Math.min(*) devient inutile car il conservera ces valeurs sur la taille maximale, et dira que la valeur mesurée WRAP_CONTENT est plus grande que notre taille maximale, cette vérification ne l'attrapera pas. J'imagine que l'OP ne pensait qu'aux dimensions exactes (pour lesquelles il fonctionne parfaitement).

    public class MaxWidthLinearLayout extends LinearLayout {
    
    private int mMaxWidth = Integer.MAX_VALUE;
    
    public MaxWidthLinearLayout(Context context) {
    
        super(context);
    }
    
    public MaxWidthLinearLayout(Context context, AttributeSet attrs) {
    
        super(context, attrs);
    
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout);
        mMaxWidth = a.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE);
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //get measured height
        if(getMeasuredWidth() > mMaxWidth){
            setMeasuredDimension(mMaxWidth, getMeasuredHeight());
        }
    }
    }

et l'attr xml

    <!-- MaxWidthLinearLayout -->
    <declare-styleable name="MaxWidthLinearLayout">
        <attr name="maxWidth" format="dimension" />
    </declare-styleable>

4voto

AmeyaB Points 31

Ajoutez une couche de mise en page externe ou de groupe de vues à votre fichier de mise en page actuel. La hauteur et la largeur de cette mise en page correspondront à la hauteur/largeur maximale. Maintenant, votre mise en page intérieure peut être configurée pour envelopper le contenu et est limitée par la mise en page extérieure. Par exemple

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- OuterLayout to set Max Height and Width  -- Add this ViewGroup to your layout  File  -->
    <LinearLayout
        android:id="@+id/outerLayout"
        android:layout_width="650dp"
        android:layout_height="650dp"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

-3voto

daniel Points 17

Voici une réponse simple,

Il semble que la largeur et la hauteur doivent toujours être définies ensemble. Cela fonctionne dans ma vue.

    <Button
        android:text="Center"
        android:layout_width="100dp"
        android:layout_height="fill_parent"
        android:id="@+id/selectionCenterButton"
        android:minWidth="50dp"
        android:minHeight="50dp"
        android:maxWidth="100dp"
        android:maxHeight="50dp"
        android:layout_weight="1" />

Le parent du bouton est configuré de manière à envelopper le contenu, ce qui permet de réduire l'échelle, mais jusqu'à une largeur maximale de 400 (4 boutons).

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