MotionLayout
est un type de mise en page qui vous aide à gérer le mouvement et l'animation des widgets dans votre application. MotionLayout
est une sous-classe de ConstraintLayout
et s'appuie sur ses nombreuses fonctionnalités de mise en page. Dans la bibliothèque ConstraintLayout
, MotionLayout
est disponible en tant que bibliothèque de compatibilité.
MotionLayout
fait le lien entre les transitions de mise en page et la gestion complexe des mouvements, en offrant une combinaison de fonctionnalités entre le framework d'animation des propriétés, TransitionManager
et CoordinatorLayout
.
En plus de décrire les transitions entre les mises en page, MotionLayout
vous permet d'animer toutes les propriétés de mise en page. De plus, il est intrinsèquement compatible avec les transitions accessibles. Cela signifie que vous pouvez afficher instantanément n'importe quel point de la transition en fonction d'une condition, telle qu'une entrée tactile. MotionLayout
est également compatible avec les clés-images, ce qui permet de créer des transitions entièrement personnalisées en fonction de vos besoins.
MotionLayout
est entièrement déclaratif, ce qui signifie que vous pouvez décrire toutes les transitions au format XML, même si elles sont complexes.
Considérations de conception
MotionLayout
est destiné à déplacer, redimensionner et animer les éléments d'interface utilisateur avec lesquels les utilisateurs interagissent, tels que les boutons et les barres de titre. N'utilisez pas le mouvement dans votre application comme un effet spécial sans frais. Utilisez-le pour aider les utilisateurs à comprendre ce que fait votre application. Pour en savoir plus sur la conception de votre application avec du mouvement, consultez la section Comprendre le mouvement de Material Design.
Premiers pas
Pour commencer à utiliser MotionLayout
dans votre projet, procédez comme suit :
-
Ajoutez la dépendance
ConstraintLayout
:pour utiliserMotionLayout
dans votre projet, ajoutez la dépendanceConstraintLayout
2.0 au fichierbuild.gradle
de votre application. Si vous utilisez AndroidX, ajoutez la dépendance suivante:Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01") }
-
Créer un fichier
MotionLayout
:MotionLayout
est une sous-classe deConstraintLayout
. Vous pouvez donc transformer n'importe quelConstraintLayout
existant enMotionLayout
en remplaçant le nom de la classe dans votre fichier de ressources de mise en page, comme illustré dans les exemples suivants:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
Bibliothèque Support
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
Voici un exemple complet de fichier
MotionLayout
, qui définit la mise en page illustrée à la figure 1:AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>
Bibliothèque Support
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
-
Créez une MotionScene:dans l'exemple
MotionLayout
précédent, l'attributapp:layoutDescription
fait référence à une scène de mouvement. Une scène de mouvement est un fichier de ressources XML. Dans son élément racine<MotionScene>
, une scène de mouvement contient toutes les descriptions de mouvement pour la mise en page correspondante. Pour séparer les informations de mise en page des descriptions de mouvement, chaqueMotionLayout
fait référence à une scène de mouvement distincte. Les définitions de la scène de mouvement prévalent sur toute définition similaire dans leMotionLayout
.Voici un exemple de fichier de scène de mouvement qui décrit le mouvement horizontal de base de la figure 1:
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>
Remarques :
-
<Transition>
contient la définition de base du mouvement.-
motion:constraintSetStart
etmotion:constraintSetEnd
sont des références aux points de terminaison du mouvement. Ces points de terminaison sont définis dans les éléments<ConstraintSet>
plus tard dans la scène de mouvement. -
motion:duration
spécifie le nombre de millisecondes nécessaire pour que le mouvement se termine.
-
-
<OnSwipe>
vous permet de créer une commande tactile pour le mouvement.-
motion:touchAnchorId
fait référence à la vue que l'utilisateur peut balayer et faire glisser. -
motion:touchAnchorSide
signifie que la vue est déplacée depuis le côté droit. -
motion:dragDirection
fait référence à la direction de progression du déplacement. Par exemple,motion:dragDirection="dragRight"
signifie que la progression augmente à mesure que la vue est déplacée vers la droite.
-
-
<ConstraintSet>
est l'endroit où vous définissez les différentes contraintes qui décrivent votre mouvement. Dans cet exemple, un<ConstraintSet>
est défini pour chaque point de terminaison de votre mouvement. Ces points de terminaison sont centrés verticalement à l'aide deapp:layout_constraintTop_toTopOf="parent"
etapp:layout_constraintBottom_toBottomOf="parent"
. Horizontalement, les points de terminaison se trouvent tout à gauche et tout à droite de l'écran.
Pour en savoir plus sur les différents éléments compatibles avec une scène de mouvement, consultez les exemples de MotionLayout.
-
Attributs interpolés
Dans un fichier de scène de mouvement, les éléments ConstraintSet
peuvent contenir des attributs supplémentaires qui sont interpolés lors de la transition. En plus de la position et des limites, les attributs suivants sont interpolés par MotionLayout
:
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,scaleY
Attributs personnalisés
Dans un élément <Constraint>
, vous pouvez utiliser l'élément <CustomAttribute>
pour spécifier une transition pour les attributs qui ne sont pas simplement liés à la position ou aux attributs View
.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
Un <CustomAttribute>
contient deux attributs qui lui sont propres:
motion:attributeName
est obligatoire et doit correspondre à un objet avec les méthodes getter et setter. Les getter et setter doivent correspondre à un modèle spécifique. Par exemple,backgroundColor
est accepté, car la vue comporte des méthodesgetBackgroundColor()
etsetBackgroundColor()
sous-jacentes.- L'autre attribut que vous devez fournir dépend du type de valeur. Choisissez parmi les types compatibles suivants :
motion:customColorValue
pour les couleursmotion:customIntegerValue
pour les entiersmotion:customFloatValue
pour les nombres à virgule flottantemotion:customStringValue
pour les chaînesmotion:customDimension
pour les dimensionsmotion:customBoolean
pour les valeurs booléennes
Lorsque vous spécifiez un attribut personnalisé, définissez les valeurs du point de terminaison dans les éléments <ConstraintSet>
de début et de fin.
Modifier la couleur d'arrière-plan
En nous appuyant sur l'exemple précédent, supposons que vous souhaitiez que les couleurs de la vue changent dans le cadre de son mouvement, comme illustré dans la figure 2.
Ajoutez un élément <CustomAttribute>
à chaque élément ConstraintSet
, comme indiqué dans l'extrait de code suivant:
<ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#9999FF" /> </Constraint> </ConstraintSet>
Attributs MotionLayout supplémentaires
En plus des attributs de l'exemple précédent, MotionLayout
présente d'autres attributs que vous pouvez spécifier:
app:applyMotionScene="boolean"
indique si la scène de mouvement doit être appliquée. La valeur par défaut de cet attribut esttrue
.app:showPaths="boolean"
indique si les trajectoires d'animation doivent être affichées pendant l'exécution du mouvement. La valeur par défaut de cet attribut estfalse
.app:progress="float"
vous permet de spécifier explicitement la progression de la transition. Vous pouvez utiliser n'importe quelle valeur à virgule flottante de0
(début de la transition) à1
(fin de la transition).app:currentState="reference"
vous permet de spécifier unConstraintSet
spécifique.app:motionDebug
vous permet d'afficher des informations de débogage supplémentaires sur le mouvement. Les valeurs possibles sont"SHOW_PROGRESS"
,"SHOW_PATH"
ou"SHOW_ALL"
.
Ressources supplémentaires
Pour en savoir plus sur MotionLayout
, consultez les ressources suivantes:
- Développement Android avancé en Kotlin 03.2: animation avec MotionLayout
- Exemples de MotionLayout
- Exemples MotionLayout/ConstraintLayout sur GitHub
- Présentation de MotionLayout (partie I)
- Présentation de MotionLayout (partie II)
- Présentation de MotionLayout (partie III)
- Présentation de MotionLayout (partie IV)