Créer une UI responsive avec ConstraintLayout Fait partie d'Android Jetpack.
ConstraintLayout vous permet de créer des mises en page volumineuses et complexes avec une hiérarchie des vues à plat (sans groupes de vues imbriqués). Il est semblable à RelativeLayout, car toutes les vues sont mises en page en fonction des relations entre les vues frères et la mise en page parente. Toutefois, il est plus flexible que RelativeLayout et plus facile à utiliser avec l'éditeur de mise en page d'Android Studio.
Toute la puissance de ConstraintLayout est disponible directement à partir des outils visuels de l'éditeur de mise en page, car l'API de mise en page et l'éditeur de mise en page sont spécialement conçus l'un pour l'autre. Vous pouvez créer votre mise en page avec ConstraintLayout entièrement par glisser-déposer au lieu de modifier le code XML.
Cette page explique comment créer une mise en page avec ConstraintLayout dans Android Studio 3.0 ou version ultérieure. Pour en savoir plus sur l'éditeur de mise en page, consultez Créer une UI avec l'éditeur de mise en page.
Pour découvrir différents types de mises en page que vous pouvez créer avec ConstraintLayout, consultez le projet d'exemples de ConstraintLayout sur GitHub.
Présentation des contraintes
Pour définir la position d'une vue dans ConstraintLayout, vous devez ajouter au moins une contrainte horizontale et une contrainte verticale pour la vue. Chaque contrainte représente une connexion ou un alignement sur une autre vue, la mise en page parente ou une ligne directrice invisible. Chaque contrainte définit la position de la vue le long de l'axe vertical ou horizontal. Chaque vue doit comporter au moins une contrainte pour chaque axe, mais il en faut souvent davantage.
Lorsque vous déposez une vue dans l'éditeur de mise en page, elle reste à l'endroit où vous l'avez déposée, même si elle n'a pas de contraintes. Cela permet simplement de faciliter la modification. Si une vue ne comporte aucune contrainte lorsque vous exécutez votre mise en page sur un appareil, elle est dessinée à la position [0,0] (en haut à gauche).
Dans la figure 1, la mise en page semble correcte dans l'éditeur, mais il n'y a aucune contrainte verticale sur la vue C. Lorsque cette mise en page est dessinée sur un appareil, la vue C s'aligne horizontalement sur les bords gauche et droit de la vue A, mais elle apparaît en haut de l'écran, car elle ne comporte aucune contrainte verticale.
Figure 1. L'éditeur affiche la vue C sous la vue A, mais sans contrainte verticale.
Figure 2. La vue C est désormais contrainte verticalement sous la vue A.
Bien qu'une contrainte manquante n'entraîne pas d'erreur de compilation, l'éditeur de mise en page indique les contraintes manquantes comme des erreurs dans la barre d'outils. Pour afficher les erreurs et autres avertissements, cliquez sur Afficher les avertissements et les erreurs
.
Pour vous aider à ne pas oublier de contraintes, l'éditeur de mise en page en ajoute automatiquement grâce aux fonctionnalités Connexion automatique et Contrainte d'inférence.
Ajouter ConstraintLayout à votre projet
Pour utiliser ConstraintLayout dans votre projet, procédez comme suit :
- Assurez-vous que le dépôt
maven.google.comest déclaré dans votre fichiersettings.gradle:Groovy
dependencyResolutionManagement { ... repositories { google() } )
Kotlin
dependencyResolutionManagement { ... repositories { google() } }
- Ajoutez la bibliothèque en tant que dépendance dans le fichier
build.gradleau niveau du module, comme indiqué dans l'exemple suivant. La dernière version peut être différente de celle présentée dans l'exemple.Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.1" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.1") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1") }
- Dans la barre d'outils ou dans la notification de synchronisation, cliquez sur Synchroniser le projet avec les fichiers Gradle.
Vous êtes maintenant prêt à créer votre mise en page avec ConstraintLayout.
Convertir une mise en page
Figure 3. Menu permettant de convertir une mise en page en ConstraintLayout.
Pour convertir une mise en page existante en mise en page de contraintes, procédez comme suit :
- Ouvrez votre mise en page dans Android Studio, puis cliquez sur l'onglet Design (Conception) en bas de la fenêtre de l'éditeur.
- Dans la fenêtre Component Tree (Arborescence des composants), effectuez un clic droit sur la mise en page, puis cliquez sur Convert LinearLayout to ConstraintLayout (Convertir LinearLayout en ConstraintLayout).
Créer une nouvelle mise en page
Pour démarrer un fichier de mise en page de contraintes, procédez comme suit :
- Dans la fenêtre Project (Projet), cliquez sur le dossier du module, puis sélectionnez File > New > XML > Layout XML (Fichier > Nouveau > XML > XML de mise en page).
- Saisissez un nom pour le fichier de mise en page, puis saisissez "androidx.constraintlayout.widget.ConstraintLayout" pour Root Tag (Tag racine).
- Cliquez sur Terminer.
Ajouter ou supprimer une contrainte
Pour ajouter une contrainte :
Vidéo 1. Le côté gauche d'une vue est contraint au côté gauche du parent.
Faites glisser une vue de la fenêtre Palette vers l'éditeur.
Lorsque vous ajoutez une vue dans un
ConstraintLayout, elle s'affiche dans un cadre de délimitation avec des poignées de redimensionnement carrées à chaque angle et des poignées de contrainte circulaires de chaque côté.- Cliquez sur la vue pour la sélectionner.
- Effectuez l'une des opérations suivantes :
- Cliquez sur une poignée de contrainte et faites-la glisser vers un point d'ancrage disponible. Ce point peut être le bord d'une autre vue, le bord de la mise en page ou une ligne directrice. Notez que lorsque vous faites glisser la poignée de contrainte, l'éditeur de mise en page affiche les ancres de connexion potentielles et les calques bleus.
Cliquez sur l'un des boutons Create a connection (Créer une connexion)
dans la section Layout (Mise en page) de la fenêtre Attributes (Attributs), comme illustré à la figure 4.
Figure 4. La section Mise en page de la fenêtre Attributs vous permet de créer des connexions.
Lorsque la contrainte est créée, l'éditeur lui attribue une marge par défaut pour séparer les deux vues.
Lorsque vous créez des contraintes, n'oubliez pas les règles suivantes :
- Chaque vue doit comporter au moins deux contraintes : une horizontale et une verticale.
- Vous ne pouvez créer des contraintes qu'entre une poignée de contrainte et un point d'ancrage qui partagent le même plan. Les plans verticaux (côtés gauche et droit) d'une vue ne peuvent être contraints qu'à un autre plan vertical, et les lignes de base ne peuvent être contraintes qu'à d'autres lignes de base.
- Chaque handle de contrainte ne peut être utilisé que pour une seule contrainte, mais vous pouvez créer plusieurs contraintes à partir de différentes vues vers le même point d'ancrage.
Pour supprimer une contrainte, vous pouvez procéder de l'une des manières suivantes :
- Cliquez sur une contrainte pour la sélectionner, puis cliquez sur Supprimer.
Cliquez en maintenant la touche Ctrl enfoncée (Cmd + clic sous macOS) sur l'ancre d'une contrainte. La contrainte devient rouge pour indiquer que vous pouvez cliquer dessus pour la supprimer, comme illustré dans la figure 5.
Figure 5. Une contrainte rouge indique que vous pouvez cliquer dessus pour la supprimer.
Dans la section Mise en page de la fenêtre Attributs, cliquez sur un ancrage de contrainte, comme illustré dans la figure 6.
Figure 6. Cliquez sur une ancre de contrainte pour la supprimer.
Vidéo 2 Ajouter une contrainte qui s'oppose à une contrainte existante.
Si vous ajoutez des contraintes opposées sur une vue, les lignes de contrainte s'enroulent comme un ressort pour indiquer les forces opposées, comme illustré dans la vidéo 2. L'effet est plus visible lorsque la taille de la vue est définie sur "fixed" (fixe) ou "wrap content" (adapter au contenu), auquel cas la vue est centrée entre les contraintes. Si vous souhaitez plutôt que la vue étire sa taille pour respecter les contraintes, définissez la taille sur "Correspondre aux contraintes". Si vous souhaitez conserver la taille actuelle, mais déplacer la vue pour qu'elle ne soit pas centrée, ajustez le biais de contrainte.
Vous pouvez utiliser des contraintes pour obtenir différents types de comportement de mise en page, comme décrit dans les sections suivantes.
Position du parent
Contraint le côté d'une vue au bord correspondant de la mise en page.
Dans la figure 7, le côté gauche de la vue est relié au bord gauche de la mise en page parente. Vous pouvez définir la distance par rapport au bord avec une marge.
Figure 7. Contrainte horizontale au parent.
Position de la commande
Définissez l'ordre d'affichage de deux vues, verticalement ou horizontalement.
Dans la figure 8, B est contraint d'être toujours à droite de A, et C est contraint d'être en dessous de A. Toutefois, ces contraintes n'impliquent pas d'alignement. B peut donc toujours se déplacer de haut en bas.
Figure 8. Contrainte horizontale et verticale.
Alignement
Alignez le bord d'une vue sur le même bord d'une autre vue.
Dans la figure 9, le côté gauche de B est aligné sur le côté gauche de A. Si vous souhaitez aligner les centres de vue, créez une contrainte des deux côtés.
Vous pouvez décaler l'alignement en faisant glisser la vue vers l'intérieur à partir de la contrainte. Par exemple, la figure 10 montre B avec un alignement de décalage de 24 dp. Le décalage est défini par la marge de la vue contrainte.
Vous pouvez également sélectionner toutes les vues que vous souhaitez aligner, puis cliquer sur Aligner
dans la barre d'outils pour sélectionner le type d'alignement.
Figure 9. Contrainte d'alignement horizontal.
Figure 10. Contrainte d'alignement horizontal avec décalage.
Alignement de référence
Alignez la ligne de base du texte d'une vue sur celle d'une autre vue.
Dans la figure 11, la première ligne de B est alignée sur le texte de A.
Pour créer une contrainte de ligne de base, effectuez un clic droit sur la vue de texte que vous souhaitez contraindre, puis cliquez sur Afficher la ligne de base. Cliquez ensuite sur la ligne de base du texte et faites-la glisser vers une autre ligne de base.
Figure 11. Contrainte d'alignement de référence.
Limiter à une ligne directrice
Vous pouvez ajouter un repère vertical ou horizontal qui vous permet de contraindre vos vues et qui est invisible pour les utilisateurs de votre application. Vous pouvez positionner le repère dans la mise en page en fonction d'unités dp ou d'un pourcentage par rapport au bord de la mise en page.
Pour créer un repère, cliquez sur Repères
dans la barre d'outils, puis sur Ajouter un repère vertical ou Ajouter un repère horizontal.
Faites glisser la ligne en pointillés pour la repositionner, puis cliquez sur le cercle situé au bord du repère pour activer ou désactiver le mode de mesure.
Figure 12. Vue contrainte à une ligne de repère.
Limiter à une barrière
Semblable à un repère, une barrière est une ligne invisible à laquelle vous pouvez contraindre les vues, sauf qu'une barrière ne définit pas sa propre position. Au lieu de cela, la position de la barrière se déplace en fonction de la position des vues qu'elle contient. Cela s'avère utile lorsque vous souhaitez contraindre une vue à un ensemble de vues plutôt qu'à une vue spécifique.
Par exemple, dans la figure 13, la vue C est limitée au côté droit d'une barrière. La barrière est définie sur la "fin" (ou sur le côté droit, dans une mise en page de gauche à droite) des vues A et B. La barrière se déplace selon que le côté droit de la vue A ou de la vue B est le plus à droite.
Pour créer une barrière, procédez comme suit :
- Cliquez sur Consignes
dans la barre d'outils, puis sur Ajouter une barrière verticale ou Ajouter une barrière horizontale. - Dans la fenêtre Arborescence des composants, sélectionnez les vues que vous souhaitez placer dans la barrière, puis faites-les glisser dans le composant de barrière.
- Sélectionnez la barrière dans l'arborescence des composants, ouvrez la fenêtre Attributs
, puis définissez barrierDirection.
Vous pouvez maintenant créer une contrainte d'une autre vue à la barrière.
Vous pouvez également contraindre les vues à l'intérieur de la barrière à la barrière. Vous pouvez ainsi aligner toutes les vues de la barrière les unes par rapport aux autres, même si vous ne savez pas quelle vue est la plus longue ou la plus haute.
Vous pouvez également inclure un repère à l'intérieur d'une barrière pour garantir une position "minimale" pour la barrière.
Figure 13. La vue C est contrainte par une barrière qui se déplace en fonction de la position et de la taille des vues A et B.
Ajuster le biais de contrainte
Lorsque vous ajoutez une contrainte aux deux côtés d'une vue et que la taille de la vue pour la même dimension est "fixed" (fixe) ou "wrap content" (adapter au contenu), la vue est centrée entre les deux contraintes avec un biais de 50% par défaut. Vous pouvez ajuster le biais en faisant glisser le curseur de biais dans la fenêtre Attributes (Attributs) ou en faisant glisser la vue, comme indiqué dans la vidéo 3.
Si vous souhaitez plutôt que la vue étende sa taille pour respecter les contraintes, définissez la taille sur "Correspondre aux contraintes".
Vidéo 3 Ajustement du biais de contrainte.
Ajuster la taille de la vue
Figure 14. Lorsque vous sélectionnez une vue, la fenêtre Attributs inclut des commandes pour 1 le ratio de taille, 2 la suppression des contraintes, 3 le mode de hauteur ou de largeur, 4 les marges et 5 le biais de contrainte. Vous pouvez également mettre en surbrillance des contraintes individuelles dans l'éditeur de mise en page en cliquant dessus dans la liste des contraintes 6.
Vous pouvez utiliser les poignées d'angle pour redimensionner une vue, mais cela code en dur la taille. La vue ne se redimensionne pas pour différents contenus ou tailles d'écran. Pour sélectionner un autre mode de dimensionnement, cliquez sur une vue et ouvrez la fenêtre Attributes
à droite de l'éditeur.
L'inspecteur de vue se trouve près du haut de la fenêtre Attributes (Attributs). Il inclut des commandes pour plusieurs attributs de mise en page, comme illustré à la figure 14. Cette option n'est disponible que pour les vues dans une mise en page contrainte.
Vous pouvez modifier la façon dont la hauteur et la largeur sont calculées en cliquant sur les symboles indiqués par le repère 3 de la figure 14. Ces symboles représentent le mode de taille comme suit. Cliquez sur le symbole pour basculer entre ces paramètres :
-
Fixe : spécifiez une dimension dans la zone de texte suivante ou en redimensionnant la vue dans l'éditeur. -
Envelopper le contenu : la vue se développe uniquement selon les besoins de son contenu. - layout_constrainedWidth
-
Contraintes de correspondance : la vue s'étend autant que possible pour respecter les contraintes de chaque côté, après avoir tenu compte des marges de la vue. Toutefois, vous pouvez modifier ce comportement avec les attributs et valeurs suivants. Ces attributs ne prennent effet que lorsque vous définissez la largeur de la vue sur "match constraints" (correspondre aux contraintes) :
- layout_constraintWidth_min
Cela prend une dimension
dppour la largeur minimale de la vue. - layout_constraintWidth_max
Cela prend une dimension
dppour la largeur maximale de la vue.
Toutefois, si la dimension donnée ne comporte qu'une seule contrainte, la vue s'étend pour s'adapter à son contenu. Si vous utilisez ce mode pour la hauteur ou la largeur, vous pouvez également définir un ratio de taille.
- layout_constraintWidth_min
Définissez cette valeur sur true pour permettre à la dimension horizontale de changer afin de respecter les contraintes. Par défaut, un widget défini sur WRAP_CONTENT n'est pas limité par des contraintes.
Définir la taille sous forme de ratio
Figure 15. La vue est définie sur un format 16:9 avec la largeur basée sur un rapport de la hauteur.
Vous pouvez définir la taille de la vue sur un ratio, tel que 16:9, si au moins l'une des dimensions de la vue est définie sur "correspondre aux contraintes" (0dp). Pour activer le ratio, cliquez sur Activer/Désactiver la contrainte de format (repère 1 sur la figure 14) et saisissez le ratio width:height dans le champ de saisie qui s'affiche.
Si la largeur et la hauteur sont définies sur "S'adapter aux contraintes", vous pouvez cliquer sur Activer/Désactiver la contrainte de proportions pour sélectionner la dimension basée sur un ratio de l'autre. L'inspecteur de vue indique quelle dimension est définie comme ratio en reliant les bords correspondants par une ligne continue.
Par exemple, si vous définissez les deux côtés sur "Correspondre aux contraintes", cliquez deux fois sur Activer/Désactiver la contrainte de proportions pour définir la largeur comme un ratio de la hauteur. La taille entière est dictée par la hauteur de la vue, qui peut être définie de n'importe quelle manière, comme illustré à la figure 15.
Ajuster les marges de la vue
Pour espacer uniformément vos vues, cliquez sur Marge
dans la barre d'outils pour sélectionner la marge par défaut de chaque vue que vous ajoutez à la mise en page. Toute modification apportée à la marge par défaut ne s'applique qu'aux vues que vous ajoutez à partir de ce moment-là.
Vous pouvez contrôler la marge de chaque vue dans la fenêtre Attributes (Attributs) en cliquant sur le nombre de la ligne qui représente chaque contrainte. Dans la figure 14, l'annotation 4 montre que la marge inférieure est définie sur 16 dp.
Figure 16. Bouton Marge de la barre d'outils.
Toutes les marges proposées par l'outil sont des multiples de 8 dp pour aider vos vues à s'aligner sur les recommandations de la grille carrée de 8 dp de Material Design.
Contrôler des groupes linéaires avec une chaîne
Figure 17. Chaîne horizontale avec deux vues.
Une chaîne est un groupe de vues liées les unes aux autres par des contraintes de position bidirectionnelles. Les vues d'une chaîne peuvent être réparties verticalement ou horizontalement.
Figure 18. Exemples de chaque style de chaîne.
Vous pouvez appliquer un style aux chaînes de l'une des manières suivantes :
- Répartition : les vues sont réparties de manière égale après la prise en compte des marges. Il s'agit de la valeur par défaut.
- Répartition à l'intérieur : les vues de début et de fin sont fixées aux contraintes à chaque extrémité de la chaîne, et les autres sont réparties de manière uniforme.
- Pondéré : lorsque la chaîne est définie sur spread ou spread inside, vous pouvez remplir l'espace restant en définissant un ou plusieurs affichages sur "match constraints" (
0dp). Par défaut, l'espace est réparti de manière égale entre chaque affichage défini sur "match constraints", mais vous pouvez attribuer un poids d'importance à chaque affichage à l'aide des attributslayout_constraintHorizontal_weightetlayout_constraintVertical_weight. Cela fonctionne de la même manière quelayout_weightdans une mise en page linéaire : la vue avec la valeur de pondération la plus élevée obtient le plus d'espace, et les vues qui ont la même pondération obtiennent la même quantité d'espace. - Packed : les vues sont regroupées après la prise en compte des marges. Vous pouvez ajuster le biais de l'ensemble de la chaîne (vers la gauche ou la droite, ou vers le haut ou le bas) en modifiant le biais de vue de la "tête" de la chaîne.
La vue "tête" de la chaîne (la vue la plus à gauche dans une chaîne horizontale (dans une mise en page de gauche à droite) et la vue la plus en haut dans une chaîne verticale) définit le style de la chaîne dans le fichier XML.
Toutefois, vous pouvez basculer entre les options Étalé, Étalé à l'intérieur et Empilé en sélectionnant une vue dans la chaîne, puis en cliquant sur le bouton de chaîne
qui s'affiche sous la vue.
Pour créer une chaîne, procédez comme suit, comme indiqué dans la vidéo 4 :
- Sélectionnez toutes les vues à inclure dans la chaîne.
- Effectuez un clic droit sur l'une des vues.
- Sélectionnez Chaînes.
- Sélectionnez Centrer horizontalement ou Centrer verticalement.
Vidéo 4 Créer une chaîne horizontale.
Voici quelques éléments à prendre en compte lorsque vous utilisez des chaînes :
- Une vue peut faire partie d'une chaîne horizontale et verticale, ce qui vous permet de créer des mises en page en grille flexibles.
- Une chaîne ne fonctionne correctement que si chaque extrémité est contrainte à un autre objet sur le même axe, comme illustré à la figure 14.
- Bien que l'orientation d'une chaîne soit verticale ou horizontale, l'utilisation de l'une d'elles n'aligne pas les vues dans cette direction. Pour que chaque vue de la chaîne soit correctement positionnée, incluez d'autres contraintes, telles que les contraintes d'alignement.
Créer automatiquement des contraintes
Au lieu d'ajouter des contraintes à chaque vue à mesure que vous les placez dans la mise en page, vous pouvez déplacer chaque vue vers les positions souhaitées dans l'éditeur de mise en page, puis cliquer sur Inférer les contraintes
pour créer automatiquement des contraintes.
Infer Constraints (Déduire les contraintes) analyse la mise en page pour déterminer l'ensemble de contraintes le plus efficace pour toutes les vues. Il contraint les vues à leurs positions actuelles tout en offrant de la flexibilité. Vous devrez peut-être effectuer des ajustements pour que la mise en page réagisse comme vous le souhaitez pour différentes tailles et orientations d'écran.
La fonctionnalité Connexion automatique au parent est distincte et peut être activée séparément. Lorsqu'elle est activée et que vous ajoutez des vues enfants à un parent, cette fonctionnalité crée automatiquement deux contraintes ou plus pour chaque vue à mesure que vous les ajoutez à la mise en page, mais uniquement lorsqu'il est approprié de contraindre la vue à la mise en page parente. La connexion automatique ne crée pas de contraintes pour les autres vues de la mise en page.
La connexion automatique est désactivée par défaut. Pour l'activer, cliquez sur Activer la connexion automatique au parent
dans la barre d'outils de l'éditeur de mise en page.
Animations par images clés
Dans un ConstraintLayout, vous pouvez animer les modifications de la taille et de la position des éléments à l'aide de ConstraintSet et TransitionManager.
Un ConstraintSet est un objet léger qui représente les contraintes, les marges et les marges intérieures de tous les éléments enfants d'un ConstraintLayout. Lorsque vous appliquez un ConstraintSet à un ConstraintLayout affiché, la mise en page met à jour les contraintes de tous ses enfants.
Pour créer une animation à l'aide de ConstraintSet, spécifiez deux fichiers de mise en page qui servent d'images clés de début et de fin pour l'animation. Vous pouvez ensuite charger un ConstraintSet à partir du deuxième fichier d'images clés et l'appliquer au ConstraintLayout affiché.
L'exemple de code suivant montre comment animer le déplacement d'un bouton unique en bas de l'écran.
// MainActivity.kt
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.keyframe_one)
constraintLayout = findViewById(R.id.constraint_layout) // member variable
}
fun animateToKeyframeTwo() {
val constraintSet = ConstraintSet()
constraintSet.load(this, R.layout.keyframe_two)
TransitionManager.beginDelayedTransition()
constraintSet.applyTo(constraintLayout)
}
// layout/keyframe1.xml // Keyframe 1 contains the starting position for all elements in the animation // as well as final colors and text sizes. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
// layout/keyframe2.xml // Keyframe 2 contains another ConstraintLayout with the final positions. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Ressources supplémentaires
ConstraintLayout est utilisé dans l'application de démonstration Sunflower.