Créer une UI responsive avec ConstraintLayout Fait partie d'Android Jetpack.

Essayer Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment utiliser les mises en page dans Compose.

ConstraintLayout vous permet de créer des mises en page volumineuses et complexes avec une hiérarchie de vues plate (pas de groupes de vues imbriqués). Elle est semblable à RelativeLayout dans la mesure où toutes les vues sont disposées en fonction des relations entre les vues sœurs et la mise en page parente, mais elle 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 entièrement votre mise en page avec ConstraintLayout en faisant glisser le code XML au lieu de le modifier.

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 afficher les différentes mises en page que vous pouvez créer avec ConstraintLayout, consultez le projet Exemples de mises en page de contrainte 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 cette vue. Chaque contrainte représente une connexion ou un alignement à une autre vue, à la mise en page parent ou à une consigne 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 est souvent nécessaire d'en ajouter plusieurs.

Lorsque vous déposez une vue dans l'éditeur de mise en page, elle reste là où vous l'avez laissée, même si elle n'est soumise à aucune contrainte. L'objectif est de simplifier le montage. 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] (angle supérieur gauche).

Dans la figure 1, la mise en page est correcte dans l'éditeur, mais il n'y a pas de contrainte verticale sur la vue C. Lorsque cette mise en page dessine sur un appareil, l'affichage C s'aligne horizontalement sur les bords gauche et droit de la vue A, mais il apparaît en haut de l'écran, car il n'a pas de contrainte verticale.

Figure 1 : L'éditeur affiche la vue C en dessous de A, mais il n'est soumis à aucune contrainte verticale.

Figure 2. La vue C est désormais soumise à une contrainte verticale sous la vue A.

Bien qu'une contrainte manquante ne provoque pas d'erreur de compilation, l'éditeur de mise en page indique des contraintes manquantes en tant qu'erreur dans la barre d'outils. Pour afficher les erreurs et d'autres avertissements, cliquez sur Afficher les avertissements et les erreurs . Pour vous aider à éviter les contraintes manquantes, l'éditeur de mise en page ajoute automatiquement des contraintes à l'aide des fonctionnalités Connexion automatique et déduction des contraintes.

Ajouter ConstraintLayout à votre projet

Pour utiliser ConstraintLayout dans votre projet, procédez comme suit:

  1. Assurez-vous que le dépôt maven.google.com est déclaré dans votre fichier settings.gradle:

    Groovy

        dependencyResolutionManagement {
          ...
          repositories {
              google()
          }
        )
        

    Kotlin

        dependencyResolutionManagement {
          ...
          repositories {
              google()
          }
        }
        
  2. Ajoutez la bibliothèque en tant que dépendance dans le fichier build.gradle au 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.0-alpha13"
        // To use constraintlayout in compose
        implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13"
    }
    

    Kotlin

    dependencies {
        implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13")
        // To use constraintlayout in compose
        implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13")
    }
    
  3. Dans la barre d'outils ou la notification de synchronisation, cliquez sur Sync Project with Gradle Files (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 avec contrainte, procédez comme suit:

  1. Ouvrez votre mise en page dans Android Studio, puis cliquez sur l'onglet Design (Conception) en bas de la fenêtre de l'éditeur.
  2. 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 nouveau fichier de mise en page de contrainte, procédez comme suit:

  1. 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).
  2. Saisissez un nom pour le fichier de mise en page, puis saisissez "androidx.constraintlayout.widget.ConstraintLayout" pour le tag racine.
  3. Cliquez sur Finish (Terminer).

Ajouter ou supprimer une contrainte

Pour ajouter une contrainte, procédez comme suit:

Vidéo 1. Le côté gauche d'une vue est limité au côté gauche du parent.

  1. 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é.

  2. Cliquez sur la vue pour la sélectionner.
  3. 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 des ancres de connexion potentielles et des superpositions bleues.
    • 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é dans la figure 4.

      Figure 4. La section Layout (Mise en page) de la fenêtre Attributes (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, tenez compte des règles suivantes:

  • Chaque vue doit avoir 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 partageant le même plan. Un plan vertical (les côtés gauche et droit) d'une vue ne peut être limité qu'à un autre plan vertical, et les lignes de référence ne peuvent être limitées qu'à d'autres lignes de base.
  • Chaque poignée de contrainte ne peut être utilisée que pour une seule contrainte, mais vous pouvez créer plusieurs contraintes à partir de différentes vues pour le même point d'ancrage.

Vous pouvez supprimer une contrainte de l'une des façons suivantes:

  • Cliquez sur une contrainte pour la sélectionner, puis cliquez sur Supprimer.
  • Cliquez en maintenant la touche Ctrl enfoncée (Cmd tout en cliquant sous macOS) sur une ancre de contrainte. La contrainte devient rouge pour indiquer que vous pouvez la supprimer en cliquant dessus, comme illustré dans la figure 5.

    Figure 5 : Une contrainte rouge indique que vous pouvez cliquer pour la supprimer.

  • Dans la section Layout (Mise en page) de la fenêtre Attributes (Attributs), cliquez sur une ancre 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 particulièrement visible lorsque la taille de la vue est définie sur "fixe" ou "encapsuler le contenu", auquel cas la vue est centrée entre les contraintes. Si vous souhaitez plutôt agrandir la vue pour respecter les contraintes, modifiez la taille pour qu'elle corresponde 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 comportements de mise en page, comme décrit dans les sections suivantes.

Position du parent

Appliquez une contrainte au côté d'une vue par rapport au bord correspondant de la mise en page.

Dans la figure 7, le côté gauche de la vue est connecté au bord gauche de la mise en page parente. Vous pouvez définir la distance à partir du bord à l'aide d'une marge.

Figure 7. : une contrainte horizontale appliquée au parent.

Position de la commande

Définissez l'ordre d'apparence de deux vues, verticalement ou horizontalement.

Dans la figure 8, B est contraint de se trouver toujours à droite de A, tandis que C est contraint de se trouver en dessous de A. Cependant, ces contraintes n'impliquent pas d'alignement. B peut donc toujours se déplacer vers le haut et vers le bas.

Figure 8. Une contrainte horizontale et verticale.

Emplacement D

Alignez le bord d'une vue sur le même bord qu'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 le centre de la 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 décalé de 24 dp. Le décalage est défini par la marge de la vue contrainte.

Vous pouvez également sélectionner toutes les vues à aligner, puis cliquer sur Aligner (Aligner) dans la barre d'outils pour sélectionner le type d'alignement.

Figure 9. Une contrainte d'alignement horizontal.

Figure 10. Une contrainte d'alignement horizontal de décalage.

Alignement de la ligne de base

Permet d'aligner 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 la partie A.

Pour créer une contrainte de référence, effectuez un clic droit sur la vue de texte à contraindre, puis cliquez sur Show Baseline (Afficher la référence). Cliquez ensuite sur la ligne de base du texte et faites glisser la ligne vers une autre ligne de base.

Figure 11 : Une contrainte d'alignement de référence.

Limiter en fonction d'une ligne directrice

Vous pouvez ajouter une ligne verticale ou horizontale qui vous permet de limiter les vues et qui est invisible pour les utilisateurs de votre application. Vous pouvez positionner la ligne de consigne 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 une consigne, cliquez sur Guidelines (Consignes) dans la barre d'outils, puis sur Add Vertical Guideline (Ajouter des consignes verticales) ou Add Horizontal Guideline (Ajouter des consignes horizontales).

Faites glisser la ligne en pointillé pour la repositionner, puis cliquez sur le cercle au bord de la ligne pour activer/désactiver le mode de mesure.

Figure 12. Vue limitée à une ligne directrice.

Limiter en fonction d'une barrière

À l'instar d'une ligne directrice, 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 change en fonction de la position des vues qu'elle contient. Cela est utile lorsque vous souhaitez limiter une vue à un ensemble de vues plutôt qu'à une vue spécifique.

Par exemple, dans la figure 13, la vue C est placée du 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) de l'affichage A et de l'affichage B. La barrière se déplace selon que le côté droit de la vue A ou de la vue B se trouve le plus à droite.

Pour créer une barrière, procédez comme suit:

  1. Cliquez sur Guidelines (Consignes) dans la barre d'outils, puis sur Add Vertical Barrier (Ajouter une barrière verticale) ou Add Horizontal Barrier (Ajouter une barrière horizontale).
  2. Dans la fenêtre Component Tree (Arborescence des composants), sélectionnez les vues que vous souhaitez intégrer à la barrière, puis faites-les glisser dans le composant de cette barrière.
  3. Sélectionnez la barrière dans l'arborescence des composants, ouvrez la fenêtre Attributes (Attributs) , puis définissez barrierDirection.

Vous pouvez maintenant créer une contrainte à partir d'une autre vue pour la barrière.

Vous pouvez également limiter les vues qui se trouvent à l'intérieur de la barrière. De cette façon, vous pouvez aligner toutes les vues de la barrière entre elles, même si vous ne savez pas quelle vue est la plus longue ou la plus haute.

Vous pouvez également inclure une consigne à l'intérieur d'une barrière pour garantir une position "minimale" de celle-ci.

Figure 13. L'affichage C est limité à 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 des deux côtés d'une vue et que la taille de la vue pour la même dimension est définie sur "fixe" ou "encapsuler le contenu", la vue est centrée entre les deux contraintes avec un biais de 50% par défaut. Vous pouvez ajuster ce biais en faisant glisser le curseur dans la fenêtre Attributes (Attributs) ou en faisant glisser la vue, comme illustré dans la vidéo 3.

Si vous souhaitez que la vue s'étire pour respecter les contraintes, modifiez la taille pour qu'elle corresponde aux contraintes.

Vidéo 3 : Ajuster le biais de contrainte.

Ajuster la taille de l'affichage

Figure 14. Lorsque vous sélectionnez une vue, la fenêtre Attributes (Attributs) inclut des commandes pour 1 format de taille, 2 contraintes de suppression, 3 modes pour la hauteur ou la largeur, 4 marges et 5 pondération 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 n'est pas redimensionnée pour les différentes tailles de contenu ou d'écran. Pour sélectionner un autre mode de dimensionnement, cliquez sur une vue et ouvrez la fenêtre Attributes (Attributs) à droite de l'éditeur.

L'inspecteur de vue en haut de la fenêtre Attributes (Attributs) contient des commandes pour plusieurs attributs de mise en page, comme illustré dans la figure 14. Cette option n'est disponible que pour les vues dans une mise en page avec contrainte.

Vous pouvez modifier la façon dont la hauteur et la largeur sont calculées en cliquant sur les symboles symbolisant la légende 3 sur la figure 14. Ces symboles représentent le mode de taille comme suit. Cliquez sur le symbole pour passer d'un paramètre à l'autre:

  • Corrigé: spécifiez une dimension spécifique dans la zone de texte suivante ou en redimensionnant la vue dans l'éditeur.
  • Encapsuler le contenu: la vue ne s'agrandit que si nécessaire pour s'adapter à son contenu.
    • layout_constrainedWidth
    • 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.

  • Match Constraints (Correspondance avec les contraintes) : la vue s'agrandit autant que possible pour respecter les contraintes de chaque côté, après avoir pris en compte ses marges. Toutefois, vous pouvez modifier ce comportement avec les attributs et valeurs suivants. Ces attributs ne s'appliquent que lorsque vous définissez la largeur de la vue sur "correspondre aux contraintes" :
    • layout_constraintWidth_min

      La largeur minimale de la vue est dp.

    • layout_constraintWidth_max

      La largeur maximale de l'affichage est de dp.

    Toutefois, si la dimension donnée ne comporte qu'une seule contrainte, l'affichage s'agrandit pour s'adapter à son contenu. L'utilisation de ce mode sur la hauteur ou la largeur vous permet également de définir un rapport de taille.

Définir la taille en tant que ratio

Figure 15. La vue est définie au format 16:9, et la largeur est basée sur le ratio de la hauteur.

Vous pouvez définir la taille de la vue sur un format, tel que 16:9, si au moins l'une de ses dimensions est définie sur "correspondre aux contraintes" (0dp). Pour activer ce ratio, cliquez sur Activer/Désactiver la contrainte de format (1 sur la figure 14) et saisissez le format width:height dans l'entrée qui s'affiche.

Si la largeur et la hauteur sont toutes deux définies sur "correspondre aux contraintes", vous pouvez cliquer sur Activer/Désactiver la contrainte de format pour sélectionner la dimension basée sur un ratio de l'autre. L'outil d'inspection de la vue indique quelle dimension est définie en tant que ratio en connectant les arêtes correspondantes à l'aide d'une ligne continue.

Par exemple, si vous définissez les deux côtés sur "Faire correspondre aux contraintes", cliquez deux fois sur Activer/Désactiver la contrainte de format pour que la largeur corresponde à la hauteur. La taille entière est déterminée par la hauteur de la vue, qui peut être définie de n'importe quelle manière, comme illustré dans la figure 15.

Ajuster les marges d'affichage

Pour espacer les vues de manière uniforme, cliquez sur Margin (Marge) dans la barre d'outils afin de sélectionner la marge par défaut pour chaque vue que vous ajoutez à la mise en page. Toute modification apportée à la marge par défaut ne s'applique qu'aux vues ajoutées par la suite.

Vous pouvez contrôler la marge de chaque vue dans la fenêtre Attributes (Attributs) en cliquant sur le numéro figurant sur la ligne qui représente chaque contrainte. Dans la figure 14, l'accroche 4 indique que la marge inférieure est définie sur 16 dp.

Figure 16. Bouton Margin (Marge) de la barre d'outils

Toutes les marges proposées par l'outil sont des facteurs de 8 dp pour que vos vues s'alignent sur les recommandations de grille carrée de 8 dp de Material Design.

Contrôler des groupes linéaires à l'aide d'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 le style aux chaînes de l'une des manières suivantes:

  1. Répartition:les vues sont réparties uniformément après la prise en compte des marges. Il s'agit de l'option par défaut.
  2. Répartir à l'intérieur:les première et dernière vues sont fixées aux contraintes de chaque extrémité de la chaîne, et le reste est réparti uniformément.
  3. Pondérée:lorsque la chaîne est définie sur spread ou spread internal, vous pouvez remplir l'espace restant en définissant une ou plusieurs vues pour qu'elles correspondent aux contraintes (0dp). Par défaut, l'espace est réparti uniformément entre chaque vue définie sur "correspondance aux contraintes", mais vous pouvez attribuer une pondération d'importance à chaque vue à l'aide des attributs layout_constraintHorizontal_weight et layout_constraintVertical_weight. Cela fonctionne de la même manière que layout_weight dans une mise en page linéaire : la vue avec la valeur de pondération la plus élevée reçoit le plus d'espace, et les vues ayant la même pondération bénéficient de la même quantité d'espace.
  4. Packed:les vues sont regroupées une fois les marges prises en compte. Vous pouvez ajuster le biais de toute la chaîne (vers la gauche ou la droite, ou vers le haut ou le bas) en modifiant le biais de la vue "head" de la chaîne.

La vue principale 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 supérieure dans une chaîne verticale) définit le style de la chaîne en XML. Toutefois, vous pouvez basculer entre spread, spread Within et Pack en sélectionnant une vue de la chaîne et en cliquant sur le bouton en forme de chaîne qui apparaît sous la vue.

Pour créer une chaîne, procédez comme suit, comme indiqué dans la vidéo 4:

  1. Sélectionnez toutes les vues à inclure dans la chaîne.
  2. Effectuez un clic droit sur l'une des vues.
  3. Sélectionnez Chaînes.
  4. Sélectionnez Centrer horizontalement ou Centrer verticalement.

Vidéo 4 : Création d'une chaîne horizontale

Voici quelques points à prendre en compte lorsque vous utilisez des chaînes:

  • Une vue peut faire partie à la fois 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é de la chaîne est contrainte par rapport à un autre objet sur le même axe, comme illustré dans la figure 14.
  • Bien que l'orientation d'une chaîne soit verticale ou horizontale, l'utilisation d'une chaîne n'aligne pas les vues dans cette direction. Pour obtenir la position appropriée pour chaque vue de la chaîne, incluez d'autres contraintes, telles que les contraintes d'alignement.

Créer automatiquement des contraintes

Au lieu d'ajouter des contraintes à chaque vue lorsque vous les placez dans la mise en page, vous pouvez déplacer chaque vue aux positions souhaitées dans l'éditeur de mise en page, puis cliquer sur Inférer des contraintes pour créer automatiquement des contraintes.

Infer Constraints (Contraintes d'inférence) analyse la mise en page pour déterminer l'ensemble de contraintes le plus efficace pour toutes les vues. Il limite les vues à leur position actuelle tout en offrant de la flexibilité. Vous devrez peut-être apporter des ajustements pour que la mise en page réponde comme vous le souhaitez pour différentes tailles et orientations d'écran.

La connexion automatique au parent est une fonctionnalité distincte que vous pouvez activer. Lorsqu'elle est activée et que vous ajoutez des vues enfants à un parent, elle crée automatiquement au moins deux contraintes pour chaque vue à mesure que vous les ajoutez à la mise en page, mais uniquement lorsqu'il est approprié de limiter la vue à la mise en page parent. 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 Enable Autoconnection to Parent (Activer la connexion automatique au parent) dans la barre d'outils de l'éditeur de mise en page.

Animations d'images clés

Dans un ConstraintLayout, vous pouvez animer les modifications apportées à la taille et à 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 la marge intérieure de tous les éléments enfants d'une ConstraintLayout. Lorsque vous appliquez un élément ConstraintSet à un élément 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 une ConstraintSet à partir du deuxième fichier d'image clé et l'appliquer à la ConstraintLayout affichée.

L'exemple de code suivant montre comment animer un seul bouton 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.