Le framework de transition d'Android vous permet d'animer toutes sortes de mouvements dans votre UI en fournissant les mises en page de début et de fin. Vous pouvez sélectionner le type d'animation souhaité, ou modifier la taille des vues, et le cadre de transition détermine comment créer une animation de la mise en page de départ à celle de fin.
Le framework de transition comprend les fonctionnalités suivantes:
- Animations au niveau du groupe: appliquer des effets d'animation à toutes les vues d'une hiérarchie de vues.
- Animations intégrées: utiliser des animations prédéfinies pour les effets courants tels que le fondu ou le mouvement ;
- Compatibilité avec les fichiers de ressources: charger des hiérarchies de vues et des animations intégrées à partir de fichiers de ressources de mise en page.
- Rappels de cycle de vie: Recevoir des rappels qui permettent de contrôler l'animation et la hiérarchie processus de changement.
Pour obtenir un exemple de code animé entre les modifications de mise en page, consultez BasicTransition :
Pour créer une animation entre deux mises en page, procédez comme suit:
- Créez un objet
Scene
pour les mises en page de début et de fin. Cependant, la scène de la mise en page de départ souvent déterminé automatiquement à partir de la mise en page actuelle. - Créer un
Transition
pour définir le type d'animation souhaité. - Appeler
TransitionManager.go()
, et le système exécute l'animation pour permuter les mises en page.
Le schéma de la figure 1 illustre la relation entre vos mises en page. les scènes, la transition et l'animation finale.
Figure 1 : Illustration de base de comment le framework de transition crée une animation.
Créer une scène
Les scènes stockent l'état d'une hiérarchie de vues, y compris toutes ses vues et leurs des valeurs de propriété. Le framework des transitions peut exécuter des animations entre et une scène finale.
Vous pouvez créer vos scènes à partir d'une mise en page un fichier de ressources ou un groupe de vues dans votre code. Toutefois, scène de départ de la transition est souvent déterminée automatiquement l'UI actuelle.
Une scène peut également définir ses propres actions à exécuter lorsque vous changez de scène. Cette fonctionnalité est utile pour nettoyer les paramètres de la vue après avoir une transition vers une scène.
Créer une scène à partir d'une ressource de mise en page
Vous pouvez créer une instance Scene
directement à partir d'une ressource de mise en page
. Utilisez cette technique lorsque la hiérarchie des vues dans le fichier est principalement statique.
La scène résultante représente l'état de la hiérarchie des vues au moment où vous
créé l'instance Scene
. Si vous modifiez la hiérarchie des vues,
à recréer la scène. Le framework crée la scène à partir de l'ensemble de la vue
dans le fichier. Vous ne pouvez pas créer de scène à partir d'une partie d'un fichier de mise en page.
Pour créer une instance Scene
à partir d'un fichier de ressources de mise en page, récupérez
la racine de la scène de votre mise en page en tant que
ViewGroup
Ensuite, appelez la méthode
Scene.getSceneForLayout()
avec la racine de la scène et l'ID de ressource du fichier de mise en page
contient la hiérarchie des vues de la scène.
Définir des mises en page pour les scènes
Les extraits de code dans le reste de cette section montrent comment créer deux
différentes scènes ayant le même élément racine. Les extraits montrent également
de pouvoir charger plusieurs objets Scene
non liés sans pour autant insinuer qu'ils
sont liés entre eux.
L'exemple comprend les définitions de mise en page suivantes:
- Mise en page principale d'une activité avec un libellé et un enfant
FrameLayout
- Un
ConstraintLayout
pour avec deux champs de texte. - Un
ConstraintLayout
pour la deuxième scène avec les deux mêmes champs de texte dans un ordre différent.
L'exemple est conçu de sorte que toute l'animation se produise dans le bloc enfant mise en page de la mise en page principale de l'activité. Libellé textuel dans la mise en page principale reste statique.
La mise en page principale de l'activité est définie comme suit:
res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/master_layout"> <TextView android:id="@+id/title" ... android:text="Title"/> <FrameLayout android:id="@+id/scene_root"> <include layout="@layout/a_scene" /> </FrameLayout> </LinearLayout>
Cette définition de mise en page contient un champ de texte et un élément FrameLayout
enfant pour la
racine de la scène. La mise en page de la première scène est incluse dans le fichier de mise en page principal.
Cela permet à l'application de l'afficher dans l'interface utilisateur initiale et de charger
dans une scène, car le framework ne peut charger que l'intégralité d'un fichier de mise en page
.
La mise en page de la première scène est définie comme suit:
res/layout/a_scene.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" ></androidx.constraintlayout.widget.ConstraintLayout>
La mise en page de la deuxième scène contient les deux mêmes champs de texte : les mêmes identifiants, placés dans un ordre différent. Elle est définie comme suit:
res/layout/another_scene.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" ></androidx.constraintlayout.widget.ConstraintLayout>
Générer des scènes à partir de mises en page
Après avoir créé des définitions pour les deux dispositions de contraintes, vous pouvez obtenir un pour chacun d'eux. Cela vous permet de passer d'une interface utilisateur à l'autre de configuration. Pour obtenir une scène, vous avez besoin d'une référence à la racine de la scène et à la mise en page. ID de ressource.
L'extrait de code suivant montre comment obtenir une référence à la racine de la scène et
Créez deux objets Scene
à partir des fichiers de mise en page:
Kotlin
val sceneRoot: ViewGroup = findViewById(R.id.scene_root) val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this) val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)
Java
Scene aScene; Scene anotherScene; // Create the scene root for the scenes in this app. sceneRoot = (ViewGroup) findViewById(R.id.scene_root); // Create the scenes. aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this); anotherScene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);
Dans l'application, deux objets Scene
sont désormais basés sur la vue.
et de hiérarchies. Les deux scènes utilisent la racine de scène définie par
Élément FrameLayout
dans res/layout/activity_main.xml
.
Créer une scène dans votre code
Vous pouvez également créer une instance Scene
dans votre code à partir d'un
ViewGroup
. Utilisez cette technique lorsque vous modifiez les hiérarchies des vues
directement dans votre code ou lorsque vous les générez de manière dynamique.
Pour créer une scène à partir d'une hiérarchie des vues dans votre code, utilisez la méthode
Scene(sceneRoot, viewHierarchy)
d'un constructeur. Appeler ce constructeur revient à appeler la fonction
Scene.getSceneForLayout()
lorsque vous avez déjà gonflé un fichier de mise en page.
L'extrait de code suivant montre comment créer un Scene
de l'élément racine de la scène et la hiérarchie des vues de la scène dans
votre code:
Kotlin
val sceneRoot = someLayoutElement as ViewGroup val viewHierarchy = someOtherLayoutElement as ViewGroup val scene: Scene = Scene(sceneRoot, viewHierarchy)
Java
Scene mScene; // Obtain the scene root element. sceneRoot = (ViewGroup) someLayoutElement; // Obtain the view hierarchy to add as a child of // the scene root when this scene is entered. viewHierarchy = (ViewGroup) someOtherLayoutElement; // Create a scene. mScene = new Scene(sceneRoot, mViewHierarchy);
Créer des actions de scène
Le framework vous permet de définir des actions de scène personnalisées que le système exécute lorsque à l'entrée ou à la sortie d'une scène. Dans de nombreux cas, la définition d'actions de scène personnalisées inutile, car le framework anime le changement entre les scènes automatiquement.
Les actions de scène sont utiles pour gérer les cas suivants:
- Pour animer des vues qui ne se trouvent pas dans la même hiérarchie. Vous pouvez animer des vues les scènes de début et de fin à l'aide d'actions de sortie et d'entrée des scènes.
- Pour animer des vues que le framework des transitions ne peut pas animer automatiquement, procédez comme suit :
tels que des objets
ListView
. Pour plus plus d'informations, consultez la section sur les limites.
Pour fournir des actions de scène personnalisées, définissez vos actions comme suit :
des objets Runnable
et les transmettre au
Scene.setExitAction()
ou Scene.setEnterAction()
fonctions. Le framework appelle la fonction setExitAction()
au niveau du
avant d'exécuter l'animation de transition et setEnterAction()
sur la scène de fin après l'exécution de l'animation de transition.
Appliquer une transition
Le cadre de transition représente le style d'animation entre les scènes avec
Transition
. Vous pouvez instancier un Transition
à l'aide de la fonction
telles que
AutoTransition
et
Fade
ou
définir votre propre transition.
Vous pouvez ensuite exécuter
l'animation entre les scènes en transmettant votre Scene
de fin
et le Transition
à
TransitionManager.go()
Le cycle de vie de la transition est semblable au cycle de vie de l'activité. les états de transition que le framework surveille entre le début la fin d'une animation. Aux états importants du cycle de vie, le framework appelle fonctions de rappel que vous pouvez implémenter pour ajuster votre interface utilisateur différentes phases de la transition.
Créer une transition
La section précédente montre comment créer des scènes représentant l'état
différentes hiérarchies de vues. Une fois les scènes de début et de fin définies,
Si vous souhaitez passer d'une animation à l'autre, créez un objet Transition
qui définit une animation.
Le framework vous permet de spécifier une transition intégrée dans un fichier de ressources
et la gonfler dans votre code, ou créer une instance de transition intégrée
directement dans votre code.
Tableau 1. Types de transition intégrés.
Classe | Taguer | Effet |
---|---|---|
AutoTransition |
<autoTransition/> |
Transition par défaut. Effectue un fondu, se déplace, se redimensionne et s'affiche en fondu dans les vues, dans cet ordre. |
ChangeBounds |
<changeBounds/> |
Déplace et redimensionne les vues. |
ChangeClipBounds |
<changeClipBounds/> |
Capture le View.getClipBounds() avant et après la scène
et anime ces changements
pendant la transition. |
ChangeImageTransform |
<changeImageTransform/> |
Capture la matrice d'une ImageView avant et après la scène
et l'anime pendant la transition. |
ChangeScroll |
<changeScroll/> |
Capture les propriétés de défilement des cibles avant et après la scène et anime les changements. |
ChangeTransform |
<changeTransform/> |
Capture l'échelle et la rotation des vues avant et après le changement de scène et anime ces changements pendant la transition. |
Explode |
<explode/> |
Suit les modifications apportées à la visibilité des vues cibles au début et à la fin et déplace des vues vers l'intérieur ou l'extérieur des bords de la scène. |
Fade |
<fade/> |
fade_in apparaît en fondu dans les vues.fade_out fait disparaître les vues en fondu.fade_in_out (par défaut) effectue une opération fade_out suivie de
fade_in .
|
Slide |
<slide/> |
Suit les modifications apportées à la visibilité des vues cibles au début et à la fin et déplace les vues vers l'intérieur ou l'extérieur de l'un des bords de la scène. |
Créer une instance de transition à partir d'un fichier de ressources
Cette technique vous permet de modifier la définition de votre transition sans modifier la de votre activité. Cette technique est également utile pour séparer les définitions de transition de votre code d'application, comme indiqué dans la section la spécification de plusieurs transitions.
Pour spécifier une transition intégrée dans un fichier de ressources, procédez comme suit:
- Ajoutez le répertoire
res/transition/
à votre projet. - Créez un fichier de ressources XML dans ce répertoire.
- Ajoutez un nœud XML pour l'une des transitions intégrées.
Par exemple, le fichier de ressources suivant spécifie la transition Fade
:
res/transition/fade_transition.xml
<fade xmlns:android="http://schemas.android.com/apk/res/android" />
L'extrait de code suivant montre comment gonfler une instance Transition
dans
votre activité à partir d'un fichier de ressources:
Kotlin
var fadeTransition: Transition = TransitionInflater.from(this) .inflateTransition(R.transition.fade_transition)
Java
Transition fadeTransition = TransitionInflater.from(this). inflateTransition(R.transition.fade_transition);
Créer une instance de transition dans votre code
Cette technique est utile pour créer des objets de transition de manière dynamique si vous modifier l'interface utilisateur dans votre code et créer une transition intégrée simple avec peu ou pas de paramètres.
Pour créer une instance de transition intégrée, appelez l'une des options
constructeurs dans les sous-classes de la classe Transition
. Par exemple,
L'extrait de code suivant crée une instance de la transition Fade
:
Kotlin
var fadeTransition: Transition = Fade()
Java
Transition fadeTransition = new Fade();
Appliquer une transition
Vous appliquez généralement une transition pour passer d'une hiérarchie de vues à une autre dans en réponse à un événement, comme une action de l'utilisateur. Prenons l'exemple d'une application de recherche: Lorsque l'utilisateur saisit un terme de recherche et appuie sur le bouton de recherche, l'application change à une scène représentant la disposition des résultats lors de l'application d'une transition fait disparaître le bouton de recherche et apparaît en fondu dans les résultats de recherche.
Pour effectuer un changement de scène lors de l’application d’une transition en réponse à un événement dans
votre activité, appelez la fonction de classe TransitionManager.go()
avec le code de fin
et l'instance de transition à utiliser pour l'animation, comme indiqué dans
l'extrait suivant:
Kotlin
TransitionManager.go(endingScene, fadeTransition)
Java
TransitionManager.go(endingScene, fadeTransition);
Le framework modifie la hiérarchie des vues dans la racine de la scène avec la vue. de la scène finale lors de l'exécution de l'animation spécifiée par la instance de transition. La scène de début est la scène de fin de la dernière transition. En l'absence de transition précédente, la scène de départ est déterminée. automatiquement à partir de l'état actuel de l'interface utilisateur.
Si vous ne spécifiez pas d'instance de transition, le gestionnaire de transition peut appliquer une
une transition automatique qui fait quelque
chose de raisonnable dans la plupart des situations. Pour
Pour plus d'informations, consultez la documentation de référence de l'API
TransitionManager
.
Choisir des vues cibles spécifiques
Le framework applique des transitions à toutes les vues dans les scènes de début et de fin
par défaut. Dans certains cas, il se peut que vous souhaitiez n'appliquer une animation qu'à un sous-ensemble
de vues dans une scène. Le framework vous permet de sélectionner des vues spécifiques
et l'animation. Par exemple, le framework ne permet pas d'animer les changements
ListView
. Par conséquent, n'essayez pas de les animer pendant une transition.
Chaque vue animée par la transition est appelée cible. Vous pouvez uniquement sélectionner des cibles qui font partie de la hiérarchie des vues associée à une scène.
Pour supprimer une ou plusieurs vues de la liste des cibles, appelez la méthode
removeTarget()
avant de démarrer la transition. Pour n'ajouter que les vues spécifiées à la
liste de cibles, appelez la
addTarget()
. Pour en savoir plus, consultez la documentation de référence de l'API
Transition
.
Spécifier plusieurs transitions
Pour optimiser l'impact d'une animation, associez-la au type de modifications entre les scènes. Par exemple, si vous supprimez certaines vues et ajoutez entre les scènes, un fondu enchaîné au moment de la création indique que certaines vues ne sont plus disponibles. Si vous déplacez des vues différents points à l'écran, il est préférable d'animer le mouvement pour que les utilisateurs remarquent le nouvel emplacement des vues.
Vous n'avez pas besoin de choisir une seule animation, car le framework des transitions permet de combiner des effets d'animation dans un ensemble de transition contenant un groupe des transitions intégrées ou personnalisées individuelles.
Pour définir un ensemble de transitions à partir d'un ensemble de transitions au format XML, créez un élément
dans le répertoire res/transitions/
et répertoriez les transitions sous
l'élément TransitionSet
. Par exemple, l'extrait de code suivant montre comment
spécifiez un ensemble de transition ayant le même comportement que AutoTransition
.
classe:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="sequential"> <fade android:fadingMode="fade_out" /> <changeBounds /> <fade android:fadingMode="fade_in" /> </transitionSet>
Pour gonfler la transition, définissez un
objet TransitionSet
dans
votre code, appelez la méthode
TransitionInflater.from()
fonction dans votre activité. La classe TransitionSet
s'étend à partir du
Transition
. Vous pouvez donc l'utiliser avec un gestionnaire de transition comme n'importe quel autre
une autre instance Transition
.
Appliquer une transition sans scènes
Modifier la hiérarchie des vues n'est pas le seul moyen de modifier votre interface utilisateur. Toi peut également apporter des modifications en ajoutant, en modifiant et en supprimant des vues enfants dans la la hiérarchie actuelle.
Par exemple, vous pouvez implémenter une interaction de recherche avec
une seule mise en page. Commencez par la mise en page montrant un champ de saisie de recherche et un champ de recherche
. Pour modifier l'interface utilisateur afin d'afficher les résultats, supprimez le bouton de recherche
lorsque l'utilisateur appuie dessus en appelant
ViewGroup.removeView()
et ajouter les résultats de recherche en appelant
ViewGroup.addView()
.
Vous pouvez utiliser cette approche si l'alternative consiste à avoir deux hiérarchies presque identiques. Plutôt que de créer et de gérer deux fichiers de mise en page distincts En raison d'une différence mineure au niveau de l'interface utilisateur, vous pouvez utiliser contenant une hiérarchie des vues que vous modifiez dans le code.
Si vous apportez des modifications dans la hiérarchie des vues actuelle de cette manière, pour créer une scène. À la place, vous pouvez créer et appliquer une transition entre deux états d'une hiérarchie de vues à l'aide d'une transition différée. Cette fonctionnalité de transition commence par l'état actuel de la hiérarchie des vues, les modifications que vous apportez à ses vues et applique une transition qui anime change lorsque le système redessine l'interface utilisateur.
Pour créer une transition différée dans une hiérarchie de vues unique, procédez comme suit : étapes:
- Lorsque l'événement qui déclenche la transition se produit, appelez la méthode
TransitionManager.beginDelayedTransition()
, fournissant ainsi la vue parent de toutes les vues et la transition à utiliser. Le framework stocke l'état des vues enfants et leurs valeurs de propriété. - Apportez les modifications nécessaires aux vues enfants selon votre cas d'utilisation. Le cadre enregistre les modifications que vous apportez aux vues enfants et à leurs propriétés.
- Lorsque le système redessine l'interface utilisateur en fonction de vos modifications, anime les changements entre l'état d'origine et le nouvel état.
L'exemple suivant montre comment animer l'ajout d'un affichage de texte à une vue. à l'aide d'une transition différée. Le premier extrait montre la mise en page fichier de définition:
res/layout/activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/inputText" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> ... </androidx.constraintlayout.widget.ConstraintLayout>
L'extrait suivant montre le code qui anime l'ajout de l'affichage de texte:
MainActivity
Kotlin
setContentView(R.layout.activity_main) val labelText = TextView(this).apply { text = "Label" id = R.id.text } val rootView: ViewGroup = findViewById(R.id.mainLayout) val mFade: Fade = Fade(Fade.IN) TransitionManager.beginDelayedTransition(rootView, mFade) rootView.addView(labelText)
Java
private TextView labelText; private Fade mFade; private ViewGroup rootView; ... // Load the layout. setContentView(R.layout.activity_main); ... // Create a new TextView and set some View properties. labelText = new TextView(this); labelText.setText("Label"); labelText.setId(R.id.text); // Get the root view and create a transition. rootView = (ViewGroup) findViewById(R.id.mainLayout); mFade = new Fade(Fade.IN); // Start recording changes to the view hierarchy. TransitionManager.beginDelayedTransition(rootView, mFade); // Add the new TextView to the view hierarchy. rootView.addView(labelText); // When the system redraws the screen to show this update, // the framework animates the addition as a fade in.
Définir des rappels de cycle de vie de transition
Le cycle de vie de la transition est semblable à celui de l'activité. Elle représente
états de transition que le framework surveille pendant la période
à la fonction TransitionManager.go()
et l'achèvement de
l'animation. Pour les états importants du cycle de vie, le framework appelle des rappels
défini par le TransitionListener
de commande.
Les rappels de cycle de vie de transition sont utiles, par exemple pour copier une vue
valeur de la propriété de la hiérarchie des vues de départ à celle des vues de fin
lors d'un changement de scène. Vous ne pouvez pas simplement copier la valeur de sa vue de départ
la vue dans la hiérarchie des vues de fin, car celle-ci n'est pas
gonflées jusqu'à la fin de la transition. Vous devez stocker la valeur
dans une variable, puis copiez-la dans la hiérarchie des vues de fin lorsque le framework
a terminé la transition. Pour recevoir une notification lorsque la transition est terminée,
implémenter
TransitionListener.onTransitionEnd()
fonction dans votre activité.
Pour en savoir plus, consultez la documentation de référence de l'API
TransitionListener
.
Limites
Cette section liste certaines limites connues du framework des transitions:
- Animations appliquées à un
SurfaceView
risque de ne pas s'afficher correctement. Les instancesSurfaceView
sont mises à jour à partir d'un thread non-UI. Par conséquent, le les mises à jour peuvent ne pas être synchronisées avec les animations d'autres vues. - Certains types de transition spécifiques peuvent ne pas produire l'effet d'animation souhaité.
lorsqu'elle est appliquée à un
TextureView
. - Classes qui étendent
AdapterView
, par exempleListView
, de gérer leurs vues enfants d'une manière incompatible avec le framework des transitions. Si vous essayez d'animer une vue en fonction deAdapterView
, l'écran de l'appareil peut cesser de répondre. - Si vous essayez de redimensionner un
TextView
avec une animation, le texte apparaît à un nouvel emplacement avant que l'objet ne soit complètement redimensionnée. Pour éviter ce problème, n'animez pas le redimensionnement des vues contenant texte.