MotionLayout
est un type de mise en page qui vous aide à gérer les animations de mouvement et de widget dans votre application.
MotionLayout est une sous-classe de
ConstraintLayout et s'appuie sur ses riches
fonctionnalités de mise en page. Faisant partie de la bibliothèque ConstraintLayout, MotionLayout est disponible en tant que bibliothèque de support.
MotionLayout comble le fossé entre les transitions de mise en page et la gestion complexe des mouvements, en offrant un mélange de fonctionnalités entre le framework d'animation de propriété,
TransitionManager et
CoordinatorLayout.
En plus de décrire les transitions entre les mises en page, MotionLayout vous permet d'animer n'importe quelle propriété de mise en page. De plus, il est compatible avec les transitions consultables. 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 images clés, ce qui permet des transitions entièrement personnalisées pour répondre à vos besoins.
MotionLayout est entièrement déclaratif, ce qui signifie que vous pouvez décrire n'importe quelle transition en XML, quelle que soit sa complexité.
Considérations de conception
MotionLayout est conçu pour 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 de mouvement dans votre application comme 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 des mouvements, consultez la
section Comprendre
le mouvement de Material Design.
Premiers pas
Suivez ces étapes pour commencer à utiliser MotionLayout dans votre projet.
-
Ajoutez la dépendance
ConstraintLayout: pour utiliserMotionLayoutdans votre projet, ajoutez la dépendanceConstraintLayout2.0 au fichierbuild.gradlede votre application. Si vous utilisez AndroidX, ajoutez la dépendance suivante :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") }
-
Créez un fichier
MotionLayout:MotionLayoutest une sous-classe deConstraintLayout. Vous pouvez donc transformer n'importe quelConstraintLayoutexistant enMotionLayouten remplaçant le nom de 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
MotionLayoutprécédent, l'attributapp:layoutDescriptionfait référence à une scène de mouvement. Une scène de mouvement est un fichier de ressources XML. Dans son<MotionScene>élément racine, 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, chaqueMotionLayoutfait référence à une scène de mouvement distincte. Les définitions de la scène de mouvement sont prioritaires par rapport à toutes les définitions similaires 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>
Veuillez noter les points suivants :
-
<Transition>contient la définition de base du mouvement.-
motion:constraintSetStartetmotion:constraintSetEndsont des références aux points de terminaison du mouvement. Ces points de terminaison sont définis dans les<ConstraintSet>éléments plus loin dans la scène de mouvement. -
motion:durationspécifie le nombre de millisecondes nécessaires pour que le mouvement se termine.
-
-
<OnSwipe>vous permet de créer une commande tactile pour le mouvement.-
motion:touchAnchorIdfait référence à la vue que l'utilisateur peut balayer et faire glisser. -
motion:touchAnchorSidesignifie que la vue est déplacée depuis le côté droit. -
motion:dragDirectionfait référence à la direction de progression du glissement. Par exemple,motion:dragDirection="dragRight"signifie que la progression augmente lorsque 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 à l'extrême gauche et à l'extrême 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 pendant la transition. Outre la position et les limites, les attributs suivants sont interpolés par MotionLayout :
alphavisibilityelevationrotation,rotationX,rotationYtranslationX,translationY,translationZscaleX,scaleY
Attributs personnalisés
Dans un <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 élément <CustomAttribute> contient deux attributs propres :
motion:attributeNameest obligatoire et doit correspondre à un objet avec des méthodes getter et setter. Le getter et le setter doivent correspondre à un modèle spécifique. Par exemple,backgroundColorest compatible, car la vue comporte des méthodesgetBackgroundColor()etsetBackgroundColor()sous-jacentes.- L'autre attribut que vous devez fournir est basé sur le type de valeur. Choisissez parmi les types compatibles suivants :
motion:customColorValuepour les couleursmotion:customIntegerValuepour les entiersmotion:customFloatValuepour les flottantsmotion:customStringValuepour les chaînesmotion:customDimensionpour les dimensionsmotion:customBooleanpour les booléens
Lorsque vous spécifiez un attribut personnalisé, définissez les valeurs des points de terminaison dans les éléments de début et de
fin <ConstraintSet>.
Modifier la couleur d'arrière-plan
En s'appuyant sur l'exemple précédent, supposons que vous souhaitez que les couleurs de la vue changent dans le cadre de son mouvement, comme illustré à la figure 2.
Ajoutez un élément <CustomAttribute> à chaque élément ConstraintSet, comme illustré 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
Outre les attributs de l'exemple précédent, MotionLayout comporte d'autres attributs que vous pouvez spécifier :
app:applyMotionScene="boolean"indique s'il faut appliquer la scène de mouvement. La valeur par défaut de cet attribut esttrue.app:showPaths="boolean"indique s'il faut afficher les chemins de mouvement 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 comprise entre0(début de la transition) et1(fin de la transition).app:currentState="reference"vous permet de spécifier unConstraintSetspécifique.app:motionDebugvous 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 – 3.2 : animation avec MotionLayout
- Exemples de MotionLayout
- Exemples de MotionLayout/ConstraintLayout sur GitHub
- Introduction à MotionLayout (partie I)
- Introduction à MotionLayout (partie II)
- Introduction à MotionLayout (partie III)
- Introduction à MotionLayout (partie IV)