Que signifie android: layout_weight?

Réponses:

860

Avec, layout_weightvous pouvez spécifier un rapport de taille entre plusieurs vues. Par exemple, vous avez un MapViewet un tablequi devraient afficher des informations supplémentaires sur la carte. La carte doit utiliser les 3/4 de l'écran et le tableau doit utiliser 1/4 de l'écran. Ensuite, vous réglerez le layout_weightdu mapà 3 et le layout_weightdu tableà 1.

Pour le faire fonctionner, vous devez également définir la hauteur ou la largeur (selon votre orientation) sur 0px.

Flo
la source
208
gratte-tête jusqu'à ce que vous mentionniez la hauteur 0px!
JohnnyLambada
24
Pour définir lequel d'entre eux sera affecté par le poids. Largeur ou hauteur.
neteinstein
30
Vous avez besoin du 0px. Exemple: vous souhaitez implémenter une table avec deux colonnes de taille égale. Chaque ligne de tableau est une disposition linéaire horizontale avec deux "cellules de tableau" (par exemple, TextViews), chacune ayant une disposition_poids = 0,5. Si vous spécifiez layout_width = "wrap_content" dans les "cellules du tableau", la largeur du contenu sera ajoutée à la largeur calculée par layout_weight, les cellules du tableau seront toutes de tailles différentes et les colonnes ne s'aligneront pas correctement. Vous devez donc définir layout_width = 0dp pour que Android utilise uniquement layout_weight pour calculer la largeur des cellules.
eeeeaaii
3
@Solace, réponse tardive, mais par souci d'exhaustivité. Il semble que l'attribut de poids ne contribue pas à RelativeLayout. Cela ne fonctionne qu'avec LinearLayout. Si vous voyez un besoin de poids, la voie à suivre est peut-être de créer un LinearLayout (avec des pondérations) dans RelativeLayout.
bbv
1
layout_weight ne fonctionne que pour une mise en page linéaire ou fonctionnera-t-il pour chaque groupe de vues.
meShakti
247

En bref, layout_weightspécifie la quantité d'espace supplémentaire dans la mise en page à allouer à la vue.

LinearLayout prend en charge l'attribution d'un poids à chaque enfant. Cet attribut attribue une valeur "d'importance" à une vue et lui permet de se développer pour remplir tout espace restant dans la vue parent. Le poids par défaut des vues est zéro.

Calcul pour attribuer tout espace restant entre l'enfant

En général, la formule est:

espace attribué à l'enfant = (poids individuel de l'enfant) / (somme du poids de chaque enfant dans la disposition linéaire)

Exemple 1

S'il y a trois zones de texte et que deux d'entre elles déclarent un poids de 1, alors que la troisième n'a pas de poids (0), l'espace restant est affecté comme suit:

1ère zone de texte = 1 / (1 + 1 + 0)

2ème zone de texte = 1 / (1 + 1 + 0)

3e zone de texte = 0 / (1 + 1 + 0)

Exemple 2

Disons que nous avons une étiquette de texte et deux éléments d'édition de texte sur une ligne horizontale. L'étiquette n'a pas de layout_weightspécification, elle occupe donc l'espace minimum requis pour le rendu. Si le layout_weightde chacun des deux éléments d'édition de texte est défini sur 1, la largeur restante dans la disposition parent sera divisée également entre eux (car nous prétendons qu'ils sont également importants).

Calcul:

1ère étiquette = 0 / (0 + 1 + 1)

2ème zone de texte = 1 / (0 + 1 + 1)

3e zone de texte = 1 / (0 + 1 + 1)

Si, au lieu de cela, la première zone de texte a un layout_weightde 1 et la deuxième zone de texte a un layout_weightde 2, alors un tiers de l'espace restant sera donné au premier et deux tiers au second (car nous revendiquons le second l'un est plus important).

Calcul:

1ère étiquette = 0 / (0 + 1 + 2)

2ème zone de texte = 1 / (0 + 1 + 2)

3ème zone de texte = 2 / (0 + 1 + 2)


Article d'origine

Arche
la source
19
Une bien meilleure explication que la réponse actuellement sélectionnée.
Teinte
12
Eh bien, il y a l'explication simple (que j'apprécie) et les petits détails (que j'apprécie d'une manière différente). Ce sont deux bonnes réponses.
cbmanica
3
Comme mentionné ailleurs, android:layout_width="0px"est important. De plus, les poids n'ont pas besoin d'être des entiers.
Brian White
C'est un peu plus difficile à comprendre que la réponse sélectionnée, mais cela donne la réponse complète - en particulier lorsque certaines vues ont des poids et d'autres pas. C'est un énorme cas d'utilisation non couvert par la réponse sélectionnée.
Acey
d'où weightSumvient l'image alors? Est-ce que cela a quelque chose à voir layout_weight?
eRaisedToX
72

en ajoutant aux autres réponses, la chose la plus importante pour que cela fonctionne est de définir la largeur (ou la hauteur) de mise en page à 0px

android:layout_width="0px"

sinon vous verrez des ordures

roetzi
la source
Je pense que cela dépend si vous voulez cacher des vues qui ne définissent pas leurs poids ou si vous voulez les montrer avec une taille adaptée et laisser l'espace libre restant aux vues "pondérées".
Andrea Leganza
Que faire si je dois configurer un poids horizontal et vertical?
Alston
40

S'il y a plusieurs vues couvrant un LinearLayout, layout_weightleur donne à chacune une taille proportionnelle. Une vue avec une plus grande layout_weightvaleur "pèse" plus, donc elle obtient un plus grand espace.

Voici une image pour rendre les choses plus claires.

entrez la description de l'image ici

Théorie

Le terme poids de mise en page est lié au concept de moyenne pondérée en mathématiques. C'est comme dans une classe universitaire où les devoirs valent 30%, la fréquentation vaut 10%, le milieu de la journée vaut 20% et la finale vaut 40%. Vos scores pour ces parties, lorsqu'ils sont pondérés ensemble, vous donnent votre note totale.

entrez la description de l'image ici

Il en va de même pour le poids de la mise en page. L' Viewshorizontale LinearLayoutpeut occuper chacune un certain pourcentage de la largeur totale. (Ou un pourcentage de la hauteur pour une verticale LinearLayout.)

La disposition

Le LinearLayoutque vous utilisez ressemblera à ceci:

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

    <!-- list of subviews -->

</LinearLayout>

Notez que vous devez utiliser layout_width="match_parent"pour le LinearLayout. Si vous utilisez wrap_content, cela ne fonctionnera pas. Notez également que layout_weightcela ne fonctionne pas pour les vues dans RelativeLayouts (voir ici et ici pour les réponses SO traitant de ce problème).

Les vues

Chaque vue dans une horizontale LinearLayoutressemble à ceci:

<Button
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1" />

Notez que vous devez utiliser layout_width="0dp"avec layout_weight="1". Oublier cela provoque de nombreux problèmes de nouveaux utilisateurs. (Voir cet article pour différents résultats que vous pouvez obtenir en ne définissant pas la largeur à 0.) Si vos vues sont verticales, LinearLayout vous les utiliserez layout_height="0dp"bien sûr.

Dans l' Buttonexemple ci-dessus, j'ai défini le poids sur 1, mais vous pouvez utiliser n'importe quel nombre. Seul le total compte. Vous pouvez voir dans les trois rangées de boutons de la première image que j'ai publiée, les nombres sont tous différents, mais comme les proportions sont les mêmes, les largeurs pondérées ne changent pas dans chaque rangée. Certaines personnes aiment utiliser des nombres décimaux qui ont une somme de 1 afin que dans une mise en page complexe, il soit clair quel est le poids de chaque pièce.

Une dernière note. Si vous disposez de nombreuses dispositions imbriquées layout_weight, cela peut nuire aux performances.

Supplémentaire

Voici la disposition xml de l'image du haut:

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

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

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="1" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:text="2" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="1" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

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

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:text="10" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="20" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:text="10" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

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

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".25"
            android:text=".25" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".50"
            android:text=".50" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".25"
            android:text=".25" />

    </LinearLayout>

</LinearLayout>
Suragch
la source
1
Je me demande toujours pourquoi plus de gens ne publient pas d'images pour accompagner leur XML. Il est beaucoup plus facile de comprendre les visuels que le code.
AleksandrH
30

layout_weightindique à Android comment distribuer vos Views dans un fichier LinearLayout. Android calcule ensuite d'abord la proportion totale requise pour tous les Views qui ont un poids spécifié et les place chacun en Viewfonction de la fraction de l'écran dont il a spécifié qu'il a besoin. Dans l'exemple suivant, Android voit que les TextViews ont un layout_weightde 0(c'est la valeur par défaut) et les EditTexts ont un layout_weightde 2chacun, tandis que le Buttona un poids de 1. Android alloue donc `` juste assez '' d'espace pour afficher tvUsername, tvPasswordpuis divise le reste de la largeur de l'écran en 5 parties égales, dont deux sont attribuées à etUsername, deux à etPasswordet la dernière partie à bLogin:

<LinearLayout android:orientation="horizontal" ...>

    <TextView android:id="@+id/tvUsername" 
    android:text="Username" 
    android:layout_width="wrap_content" ... />

    <EditText android:id="@+id/etUsername"
    android:layout_width="0dp"
    android:layout_weight="2" ... />

    <TextView android:id="@+id/tvPassword"
    android:text="Password"
    android:layout_width="wrap_content" />

    <EditText android:id="@+id/etPassword"
    android:layout_width="0dp"
    android:layout_weight="2" ... />

    <Button android:id="@+id/bLogin"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:text="Login"... />

</LinearLayout>

Il ressemble à:
orientation paysage et
orientation portrait

Tash Pemhiwa
la source
le lien n'est plus disponible. Si vous avez une autre bonne référence, veuillez la mettre à jour.
BinaryGuy
16

Pensez-y de cette façon, sera plus simple

Si vous avez 3 boutons et leurs poids sont 1,3,1 en conséquence, cela fonctionnera comme un tableau en HTML

Fournissez 5 portions pour cette ligne: 1 portion pour le bouton 1, 3 portions pour le bouton 2 et 1 portion pour le bouton 1

Qui concerne,

George Nguyen
la source
10

l'une des meilleures explications pour moi était celle-ci (à partir du tutoriel Android, recherchez l'étape 7) :

layout_weight est utilisé dans LinearLayouts pour attribuer une "importance" aux vues dans la disposition. Toutes les vues ont un poids de mise en page par défaut de zéro, ce qui signifie qu'elles occupent autant de place à l'écran qu'elles doivent être affichées. L'attribution d'une valeur supérieure à zéro divisera le reste de l'espace disponible dans la vue parente, en fonction de la valeur de la mise en page de chaque vue et de son rapport avec la mise en page globale spécifiée dans la mise en page actuelle pour cet élément et les autres éléments de la vue.

Pour donner un exemple: disons que nous avons une étiquette de texte et deux éléments d'édition de texte sur une ligne horizontale. L'étiquette n'a pas de poids de disposition spécifié, elle occupe donc l'espace minimum requis pour le rendu. Si la mise en page_poids de chacun des deux éléments d'édition de texte est définie sur 1, la largeur restante dans la mise en page parent sera répartie également entre eux (car nous affirmons qu'ils sont également importants). Si le premier a un layout_weight de 1 et le second a un layout_weight de 2, alors un tiers de l'espace restant sera donné au premier, et les deux tiers au second (car nous prétendons que le second est plus important).

Andre Steingress
la source
4

Pour plus :

Pour l' verticalorientation, n'oubliez pas de régler heightsur 0dp

android:layout_height="0dp"

Pour l' horizontalorientation, n'oubliez pas de régler widthsur 0dp

android:layout_width="0dp"
Alen Lee
la source
3

Veuillez regarder le weightSum de LinearLayout et le layout_weight de chaque vue. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" Leurs layout_height sont tous les deux 0px, mais je ne suis pas sûr que ce soit pertinent

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4">

<fragment android:name="com.example.SettingFragment"
    android:id="@+id/settingFragment"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="2"
    />

<Button
    android:id="@+id/dummy_button"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="2"
    android:text="DUMMY"
    />
</LinearLayout>
Ming Leung
la source
Veuillez regarder le weightSum de LinearLayout et le layout_weight de chaque vue. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" Leurs layout_height sont tous les deux 0px, mais je ne suis pas sûr que ce soit pertinent.
Ming Leung
0

Combiner les deux réponses de

Flo & rptwsthi et roetzi,

N'oubliez pas de changer votre layout_width=0dp/px, sinon le layout_weightcomportement agira à l'envers, le plus grand nombre occupant le plus petit espace et le plus petit nombre occupant le plus grand espace.

De plus, certaines combinaisons de poids entraîneront une certaine mise en page qui ne peut pas être affichée (car elle occupait trop l'espace).

Méfiez-vous de cela.

user2837483
la source
0

L'ajout android:autoSizeTextType="uniform"redimensionnera automatiquement le texte pour vous

skryshtafovych
la source
-1

Comme son nom l'indique, la pondération de mise en page spécifie la quantité ou le pourcentage d'espace qu'un champ ou un widget particulier doit occuper l'espace d'écran.
Si nous spécifions le poids en orientation horizontale, alors nous devons spécifier layout_width = 0px.
De même, si nous spécifions le poids en orientation verticale, alors nous devons le spécifier layout_height = 0px.

Akanksha Hegde
la source