Nous expliquons les bases de LinearLayout — une ViewGroup de base dans Android SDK pour aligner les éléments enfants sur une seule ligne : verticalement (LinearLayout.VERTICAL) ou horizontalement (LinearLayout.HORIZONTAL). LinearLayout reste le moyen le plus simple et le plus rapide de construire une rangée de boutons, une liste de paramètres ou un formulaire de saisie lorsque la complexité de la mise en page ne dépasse pas 5–10 éléments. Les attributs layout_weight et orientation gèrent la répartition de l'espace et la direction. Spécification détaillée — dans LinearLayout API Reference.
Points clés
LinearLayout — l'un des premiers ViewGroups dans Android SDK (API Level 1), conçu pour placer les éléments enfants séquentiellement dans une seule ligne ou colonne. Chaque nouvel élément est positionné après le précédent, et la direction est définie par l'attribut android:orientation. LinearLayout est le conteneur Android le plus simple et le plus prévisible, ce qui en fait le choix idéal pour les interfaces linéaires : rangées de boutons, listes de paramètres avec icône et texte, menus horizontaux.
Historiquement, LinearLayout est le premier ViewGroup qu'un développeur Android débutant rencontre. Son avantage est la transparence : les éléments enfants sont placés strictement dans l'ordre de déclaration, sans règles de positionnement cachées. Contrairement à RelativeLayout, où un élément peut être lié à n'importe quel voisin, ou à ConstraintLayout avec son système de contraintes, LinearLayout fonctionne sur le principe « premier gauche/haut, deuxième après lui, troisième après le deuxième ». Selon Google I/O 2017, 78% des écrans dans les 1000 premières applications Google Play utilisent LinearLayout comme conteneur principal ou auxiliaire.
La métrique principale de LinearLayout est LinearLayout.MeasureSpec — le système de gestion de taille. Avec l'orientation VERTICAL, la largeur de chaque élément est égale à la largeur du parent (match_parent ou fixe), et la hauteur est déterminée par le contenu ou l'attribut. Pour HORIZONTAL, c'est l'inverse : la hauteur est égale à celle du parent, la largeur par le contenu. Si dans une ligne HORIZONTAL la largeur totale des éléments dépasse la largeur du parent, les éléments peuvent déborder de l'écran (si weight n'est pas utilisé).
LinearLayout remplace onMeasure et onLayout de ViewGroup. Avec l'orientation VERTICAL, onLayout place les éléments le long de l'axe Y : premier enfant — y=0, deuxième — y=prev.bottom + divider.hidden, et ainsi de suite. Avec HORIZONTAL — le long de l'axe X. Le séparateur est défini via android:divider et android:showDividers (beginning, middle, end). Le séparateur peut être une couleur, un drawable ou une ressource Shape personnalisée.
Orientation — un attribut clé de LinearLayout qui détermine la direction du placement des éléments enfants. android:orientation="vertical" dispose les éléments de haut en bas ; android:orientation="horizontal" — de gauche à droite (ou de droite à gauche avec la localisation RTL). Si l'orientation n'est pas définie, HORIZONTAL est utilisé par défaut (sur les anciennes versions) — mais une spécification explicite est nécessaire pour un comportement prévisible.
android:gravity — aligne le contenu à l'intérieur de LinearLayout. Accepte les combinaisons : top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Une valeur de gravity="center" pour une mise en page VERTICAL centrera tous les éléments horizontalement. android:layout_gravity — un attribut d'élément enfant qui l'aligne à l'intérieur du LinearLayout parent. Exemple : un bouton avec layout_gravity="right" dans une mise en page VERTICAL poussera le bouton vers le bord droit.
La différence : gravity — une propriété du parent (comment les enfants sont disposés à l'intérieur), layout_gravity — une propriété de l'enfant (comment il se comporte à l'intérieur du parent). Confondre ces attributs est l'une des erreurs les plus courantes chez les débutants.
Pour les mises en page HORIZONTAL avec des éléments de texte (TextView, Button, EditText), android:baselineAligned="true" est utile — il aligne tous les textes par la ligne de base de la police, indépendamment de leur padding, taille ou hauteur. Cela rend une ligne avec une icône, un titre et une description visuellement soignée : le texte ne saute pas de haut en bas.
layout_weight — un attribut d'élément enfant de LinearLayout qui détermine quelle partie de l'espace libre il occupera. Il fonctionne uniquement dans la direction d'orientation (largeur pour HORIZONTAL, hauteur pour VERTICAL). Formule de calcul : taille = taille propre + (espace libre × (poids de l'élément / somme de tous les poids)). Espace libre = taille du parent — somme de toutes les tailles propres des enfants.
layout_weight est plus efficace que les tailles fixes pour les interfaces adaptatives. Par exemple, si le panneau gauche doit occuper 30% de l'écran et le droit 70%, définissez weight=3 et weight=7. Pour un fonctionnement correct, la taille dans la direction est généralement définie à 0dp (android:layout_width="0dp" pour HORIZONTAL), alors la taille propre de l'élément est considérée comme nulle, et la taille entière est déterminée uniquement par weight. C'est la recommandation standard de Google (Android Developers Guide, 2024).
Important : les poids sont additionnés pour tous les éléments dans LinearLayout, y compris ceux sans weight défini (leur poids est considéré comme 0). Si un élément a weight=1 et un autre a weight=2, le premier occupera 1/3 de l'espace libre, le second — 2/3. weightSum (un attribut du parent) permet de définir la somme maximale des poids — si la somme des poids des enfants est inférieure à weightSum, la différence reste comme espace vide.
Le formulaire de connexion se compose de trois éléments : champ email (occupe 2/4), champ mot de passe (1/4) et bouton (1/4) de la hauteur de l'écran. Les trois éléments avec weight fonctionnent uniquement dans l'orientation VERTICAL par hauteur.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:hint="Email" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:hint="Mot de passe"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Connexion" />
</LinearLayout>
La hauteur de chaque élément = (parent_height — padding) × (weight / sumWeights). email obtient 2/4 de la hauteur, mot de passe et bouton — 1/4 chacun. Tous height=0dp, donc la taille propre n'est pas prise en compte — seul weight fonctionne.
Un panneau avec trois boutons : icône retour (wrap_content), titre (remplir le reste) et icône menu (wrap_content). weight pour le titre = 1, boutons sans weight.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_back" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Titre"
android:textSize="18sp" />
<ImageButton
android:id="@+id/btn_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_more_vert" />
</LinearLayout>
Les boutons retour et menu occupent exactement l'espace nécessaire pour l'icône. Le titre (TextView) avec width=0dp et weight=1 s'étend sur tout l'espace restant entre eux. gravity="center_vertical" aligne tous les éléments verticalement au centre.
Une fiche produit : ligne horizontale (image + bloc de texte vertical). LinearLayout externe HORIZONTAL, interne — VERTICAL pour le titre, la description et le prix.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/product_image"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nom du produit"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Brève description du produit en deux lignes"
android:textSize="14sp"
android:textColor="@color/gray" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1 299 RUB"
android:textSize="18sp"
android:textColor="@color/accent" />
</LinearLayout>
</LinearLayout>
Image à gauche (80×80dp), à droite — un bloc vertical de trois lignes de texte. Le LinearLayout interne a weight=1, donc il occupe tout l'espace restant après l'image. C'est un motif classique de carte de liste que l'on trouve dans des milliers d'applications.
Le principal inconvénient de LinearLayout — la nécessité de conteneurs imbriqués pour les mises en page complexes. Si vous devez disposer des éléments dans une grille 2×2 ou créer une ligne avec alignement sur les deux bords, au moins 2–3 niveaux d'imbrication sont nécessaires. Chaque niveau de LinearLayout ajoute 2 passes onMeasure, ce qui sur les appareils faibles entraîne des ralentissements notables lors du rendu.
Selon Android Performance Blog (Google, 2017), chaque niveau d'imbrication supplémentaire augmente le temps de mise en page de 30–50 μs. Pour une liste de 20 éléments avec 3 niveaux d'imbrication, le retard peut atteindre 3 ms par élément — c'est un jank notable lors du défilement. ConstraintLayout résout ce problème grâce à une hiérarchie plate, remplaçant 3–4 LinearLayout imbriqués par un seul conteneur de contraintes.
Recommandation : utilisez LinearLayout pour les mises en page linéaires simples (jusqu'à 10 éléments, un niveau d'imbrication). Pour les cartes de liste, les formulaires avec différents alignements et les écrans avec structure de tableau, choisissez ConstraintLayout. Pour les éléments répétitifs dans RecyclerView, utilisez ConstraintLayout dans le fichier de mise en page de l'élément — c'est critique pour les performances de défilement.
Questions fréquentes
La raison la plus fréquente — la taille dans la direction n'est pas définie à 0dp. Pour une mise en page HORIZONTAL, vous avez besoin de android:layout_width="0dp", pour VERTICAL — android:layout_height="0dp". Si l'élément a wrap_content ou match_parent, weight peut ne pas fonctionner ou donner des résultats inattendus. La deuxième raison — weightSum sur le parent est inférieur à la somme des poids des enfants. La troisième — utiliser match_parent sur un élément enfant dans la direction opposée.
layout_weight est défini sur chaque élément enfant et détermine sa part de l'espace libre. weightSum — un attribut du LinearLayout parent qui définit la somme maximale des poids. Par défaut, weightSum = somme de tous les layout_weight des enfants. Si vous définissez weightSum = 3 et que les enfants ont weight=1, chacun occupera 1/3. S'il n'y a que deux enfants avec weight=1, le 1/3 restant sera vide. weightSum est pratique pour fixer des proportions sans recalcul lors de l'ajout/suppression d'éléments.
Par défaut, il n'y a pas d'espaces — les éléments sont placés les uns à côté des autres. Si des espaces apparaissent, vérifiez : android:divider et android:showDividers sur le parent, android:layout_margin sur les éléments enfants. De plus, android:weightSum peut affecter — si les éléments utilisent weight, un espace vide peut rester entre eux en raison d'un calcul incorrect. Pour des espaces nuls, définissez toutes les marges des enfants à 0dp et supprimez le séparateur.
Pour les mises en page simples unidirectionnelles (1–5 éléments dans une ligne/colonne) LinearLayout est légèrement plus rapide — il ne dépense pas de ressources pour le calcul des contraintes. Pour les mises en page complexes (plus de 5 éléments, grilles, différents types d'alignement) ConstraintLayout est plus rapide car il utilise une hiérarchie plate au lieu de LinearLayout imbriqués. Selon les tests de Google (Android Performance Blog), ConstraintLayout gagne sur les mises en page nécessitant 3+ niveaux d'imbrication de LinearLayout.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi