Nous expliquons l'essence de RelativeLayout — un ViewGroup dans Android SDK pour positionner les éléments enfants les uns par rapport aux autres ou par rapport au conteneur parent. Contrairement à LinearLayout, qui organise les éléments strictement en séquence, RelativeLayout permet de placer n'importe quel élément à gauche, à droite, au-dessus, en dessous ou centré par rapport à tout autre élément via son ID. Cela rend RelativeLayout pratique pour les mises en page complexes et superposées sans imbrication. Les règles de base sont décrites dans la documentation Android Developers.
Points clés
RelativeLayout — un ViewGroup introduit dans Android SDK à partir de l'API Level 1, qui positionne les éléments enfants via des règles déclaratives (layout rules) par rapport au parent ou à d'autres éléments enfants. Chaque règle est définie par un attribut XML tel que android:layout_above, android:layout_below, android:layout_toLeftOf avec la valeur de l'ID de l'élément cible.
Avant RelativeLayout, les développeurs devaient utiliser des LinearLayout imbriqués pour chaque positionnement non standard — cela entraînait une imbrication profonde et un rendu lent. RelativeLayout a résolu ce problème en offrant un positionnement relatif à un seul niveau hiérarchique. Cependant, sa flexibilité est limitée par rapport au ConstraintLayout moderne : RelativeLayout ne prend pas en charge les chaînes, les barrières, les guides ni les dimensions en pourcentage.
RelativeLayout a deux caractéristiques clés : un seul passage onMeasure (contrairement à LinearLayout avec weight qui nécessite deux passages) et une dépendance à l'ordre de déclaration — si l'élément A référence l'élément B, et que B est déclaré après A, B doit avoir une taille connue au moment de la mesure de A. Selon le Guide du développeur Android (2024), RelativeLayout effectue la mesure en un seul passage si toutes les règles référencent des éléments déjà mesurés. Sinon, un second passage est nécessaire, ce qui réduit les performances.
RelativeLayout est justifié pour les mises en page simples de 3 à 7 éléments nécessitant un positionnement relatif (étiquette au-dessus d'un bouton, icône à droite du texte, panneau en bas de l'écran). Pour les nouveaux projets, ConstraintLayout est recommandé, mais RelativeLayout est encore largement utilisé dans le code existant et les bibliothèques.
RelativeLayout utilise deux types de règles : les règles relative (positionnement relatif à un autre élément) et les règles align (ancrage au parent). Chaque élément enfant peut avoir un nombre illimité de règles, mais les règles conflictuelles (ex. alignParentTop et below d'un autre élément) sont résolues en faveur du dernier attribut déclaré.
Règles relative :
- android:layout_above="@id/target" — le bord inférieur de l'élément est ancré au bord supérieur de target.
- android:layout_below="@id/target" — le bord supérieur de l'élément est ancré au bord inférieur de target.
- android:layout_toLeftOf="@id/target" — le bord droit est ancré au bord gauche de target.
- android:layout_toRightOf="@id/target" — le bord gauche est ancré au bord droit de target.
- android:layout_toStartOf="@id/target" — analogue à toLeftOf pour les locales RTL.
- android:layout_toEndOf="@id/target" — analogue à toRightOf pour RTL.
Règles align (au parent) :
- android:layout_alignParentTop="true" — le bord supérieur de l'élément coïncide avec le bord supérieur du parent.
- android:layout_alignParentBottom="true" — le bord inférieur coïncide avec le bord inférieur du parent.
- android:layout_alignParentLeft="true" — le bord gauche coïncide avec le bord gauche du parent.
- android:layout_alignParentRight="true" — le bord droit coïncide avec le bord droit du parent.
- android:layout_alignParentStart et android:layout_alignParentEnd — pour RTL.
Règles align vers d'autres éléments :
- android:layout_alignTop="@id/target" — le haut de l'élément coïncide avec le haut de target.
- android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — analogue.
- android:layout_alignBaseline="@id/target" — alignement par la ligne de base du texte (utile pour les chaînes de différentes tailles de police).
Le centrage dans RelativeLayout est défini par trois attributs : android:layout_centerInParent="true" (centre du parent sur les deux axes), android:layout_centerHorizontal="true" (centre horizontal) et android:layout_centerVertical="true" (centre vertical). Le centrage est compatible avec d'autres règles : un élément peut être centré horizontalement tout en étant ancré au bord inférieur du parent.
L'ordre Z (ordre de superposition) dans RelativeLayout est déterminé par l'ordre de déclaration des éléments en XML. Le premier élément déclaré est dessiné en premier (sera en dessous), le dernier — en dernier (sera au-dessus). Si vous devez modifier l'ordre de superposition sans changer le XML, utilisez android:elevation (à partir de l'API 21) — les éléments avec une elevation plus élevée sont dessinés par-dessus. Pour les versions antérieures à l'API 21, l'ordre de superposition est contrôlé uniquement par l'ordre de déclaration.
Important : RelativeLayout ne prend pas en charge l'attribut android:elevation pour le parent — chaque élément contrôle sa propre elevation. En cas de conflit entre les règles de positionnement et l'elevation (ex. éléments qui se chevauchent), l'elevation a priorité pour le rendu, mais pas pour le positionnement — un élément avec une elevation plus élevée peut visuellement en chevaucher un autre, même si ses règles de mise en page le placent « derrière ».
Avatar centré en haut, nom sous l'avatar, statut sous le nom, bouton d'action en bas de l'écran. Tous les éléments utilisent des règles relatives pour l'ancrage séquentiel.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:src="@drawable/avatar_placeholder" />
<TextView
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/avatar"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="Ivan Ivanov"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/user_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/user_name"
android:layout_centerHorizontal="true"
android:text="En ligne"
android:textColor="@color/green" />
<Button
android:id="@+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:text="Modifier le profil" />
</RelativeLayout>
L'avatar est ancré en haut via marginTop + centerHorizontal, le nom est sous l'avatar via layout_below, le statut sous le nom, et le bouton est ancré au bord inférieur du parent via alignParentBottom. Tous les éléments sont indépendants les uns des autres — pas de chaînes ni d'imbrication.
Une icône avec un badge rouge (cercle avec chiffre) dans le coin supérieur droit. Le badge est positionné par rapport à l'icône via un alignement sur ses bords avec des marges négatives pour le chevauchement.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_notification" />
<TextView
android:id="@+id/badge"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignTop="@+id/icon"
android:layout_alignRight="@+id/icon"
android:layout_marginTop="-6dp"
android:layout_marginRight="-6dp"
android:gravity="center"
android:background="@drawable/badge_background"
android:text="3"
android:textColor="@android:color/white"
android:textSize="10sp" />
</RelativeLayout>
Le badge est ancré aux bords supérieur et droit de l'icône. Les marges négatives (-6dp) déplacent le badge vers l'extérieur, créant un effet de chevauchement de la bordure de l'icône. C'est un modèle populaire pour les notifications, qui sans RelativeLayout nécessiterait FrameLayout ou un dessin personnalisé.
Formulaire de connexion : logo centré en haut, champ email en dessous, champ mot de passe sous l'email, bouton « Connexion » sous le mot de passe, lien « S'inscrire » ancré en bas. Tous les éléments sont ancrés séquentiellement via layout_below.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dp"
android:text="MyApp"
android:textSize="32sp"
android:textStyle="bold" />
<EditText
android:id="@+id/email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/logo"
android:layout_marginTop="32dp"
android:hint="Email" />
<EditText
android:id="@+id/password_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/email_input"
android:layout_marginTop="16dp"
android:hint="Mot de passe"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/password_input"
android:layout_marginTop="24dp"
android:text="Connexion" />
<TextView
android:id="@+id/register_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:text="Pas de compte ? S'inscrire"
android:textColor="@color/primary" />
</RelativeLayout>
L'écran utilise 5 éléments à un seul niveau hiérarchique. Le flux de haut en bas (logo → email → mot de passe → bouton) est réalisé via layout_below, et le lien est poussé vers le bas via alignParentBottom. Pour la même fonctionnalité, LinearLayout nécessiterait deux conteneurs imbriqués (un pour le groupe supérieur, un pour le lien avec weight).
Comparaison de deux ViewGroups pour le positionnement relatif : RelativeLayout (classique, API 1+) et ConstraintLayout (moderne, Jetpack). Critères : flexibilité, performance, support RTL et adaptabilité.
| Caractéristique | RelativeLayout | ConstraintLayout |
|---|---|---|
| Dimensions en pourcentage | Non (fixes et match_parent uniquement) | Oui (width_percent, height_percent, guideline_percent) |
| Support RTL | Via start/end (API 17+) | Intégré |
| Chaînes | Non | Oui (spread, spread_inside, packed) |
| Barrière / Group / Flow | Non | Oui (assistants virtuels) |
| Animations MotionLayout | Non | Oui |
| Passages onMeasure | 1 (sans cycles de dépendance) | 2 (toujours, mais optimisés) |
| Centrage | centerInParent, centerHorizontal, centerVertical | Via bias (0.0–1.0) avec contraintes opposées |
| Quand utiliser | Code existant, mises en page simples avec 3–7 éléments | Nouveaux projets, écrans complexes, mises en page adaptatives |
RelativeLayout est inférieur à ConstraintLayout dans presque tous les aspects sauf un : il est intégré dans Android SDK depuis l'API 1 et ne nécessite aucune dépendance supplémentaire. Pour les projets qui utilisent encore un minSdk inférieur à l'API 14 (Android 4.0), RelativeLayout est la seule option standard pour le positionnement relatif. Dans tous les autres cas, Google recommande ConstraintLayout.
Questions fréquentes
La raison la plus probable est l'absence de règles de positionnement suffisantes. Chaque élément dans RelativeLayout doit avoir au moins une règle horizontale (alignParentLeft, toRightOf, centerHorizontal) et une règle verticale (alignParentTop, below, centerVertical). Sans règles, l'élément se trouve à la position (0,0) et peut être caché sous d'autres éléments ou hors de l'écran. La deuxième raison est une dépendance circulaire (élément A lié à B, B lié à A), qui entraîne un comportement imprévisible.
Utilisez l'attribut android:layout_centerInParent="true". Il centre l'élément sur les deux axes simultanément. Si seulement horizontalement — android:layout_centerHorizontal="true", seulement verticalement — android:layout_centerVertical="true". Le centrage fonctionne en combinaison avec les marges — l'élément sera décalé par rapport au centre du décalage spécifié.
Oui, mais ce n'est pas recommandé. RelativeLayout effectue deux passages onMeasure en présence de dépendances circulaires, ce qui est 15 à 30 % plus lent que ConstraintLayout dans les listes RecyclerView. Pour les mises en page d'éléments RecyclerView, utilisez ConstraintLayout — il offre une hiérarchie plate avec un temps de mesure minimal. Si RelativeLayout est déjà utilisé dans un projet existant, assurez-vous que les éléments ne créent pas de dépendances circulaires et mesurez les FPS de défilement via Profile GPU Rendering.
android:layout_margin définit les marges sur tous les côtés simultanément. android:layout_marginTop — seulement en haut. L'attribut le plus spécifique a la priorité : si layout_margin (16dp) et layout_marginTop (8dp) sont tous deux définis, la marge supérieure sera de 8dp. Dans RelativeLayout, la marge fonctionne par rapport à la contrainte, pas par rapport à l'élément adjacent : layout_marginTop avec layout_below="@id/target" est la marge du bord supérieur de l'élément au bord inférieur de target.
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