Introduction à MotionLayout sur Android – Denis Fodor
Le généré motion_layout_scene.xml ressemble à ça:
MotionScene est l’élément racine d’un fichier de scène de mouvement et il est utilisé pour créer des animations dans un manière déclarative. Le même MotionScene le fichier peut être réutilisé et appliqué à différentes dispositions.
le ConstraintSet l’élément a des définitions pour chaque Vue vous souhaitez animer dans une séquence de mouvements.
Contrainte L’élément spécifie les attributs et l’emplacement d’un seul Vue dans une séquence de mouvements.
Transition contient au moins le début et la fin ConstraintSet et il décrit les changements du début à l’état final. Il peut contenir Sur clic, OnSwipe et KeyFrameSet éléments.
Plus d’informations sur les éléments mentionnés peuvent être trouvées dans l’officiel Documentation.
Mais, assez de théorie, regardons notre exemple!
N’hésitez pas à consulter le dépôt Github avec le code source ci-dessous.
Notre fichier de mise en page activity_music_band_list.xml a la hiérarchie suivante:
Ici, vous pouvez voir un parent MotionLayout avec deux enfants – RecyclerView et un autre MotionLayout, contenant des vues qui seront animées. Le but du parent MotionLayout est de contrôler la visibilité de ses enfants à travers un fichier de scène de mouvement.
Avant d’approfondir l’implémentation de l’animation, je voulais mentionner qu’il s’agit d’une animation en plusieurs étapes. MotionLayout ne dispose pas actuellement d’une API pour les transitions contrôlées en plusieurs étapes. Depuis que j’ai 4 ConstraintSets et besoin de gérer 3 transitions, je dois commencer certaines transitions par programme. Pour des transitions plus complexes, avec plus d’étapes, vous pouvez voir un article écrit par Chris Banes.
Quand le RecyclerView l’élément est cliqué, nous appelons animer méthode définie dans MusicBandListActivity.
le vhValues Le paramètre est une interface avec deux méthodes qui fournissent les informations nécessaires au positionnement des vues en utilisant ConstraintSet.
le musicBandModel représente un POJO du cliqué RecyclerView article.
Tout d’abord, nous devons modifier les marges de nos vues avec les valeurs du paramètre d’interface:
private fun animate(
vhValues: MusicBandAdapter.ViewHolderValues,
musicBandModel: MusicBandModel) {val marginTop =
(vhValues.getThumbnailHeight() * SCALE).toInt() - (iconSize * SCALE / 2).toInt() - margin
animatedView.also {
var set = it.getConstraintSet(firstSet)
set.setMargin(R.id.thumbnail, ConstraintSet.TOP, vhValues.getY())
set.setVisibility(R.id.thumbnail, ConstraintSet.VISIBLE)
set.setMargin(R.id.more_info, ConstraintSet.TOP, marginTop)
set.applyTo(it)
set = it.getConstraintSet(secondSet)
set.setMargin(R.id.more_info, ConstraintSet.TOP, marginTop)
set.applyTo(it)
set = it.getConstraintSet(thirdSet)
set.setMargin(R.id.more_info, ConstraintSet.TOP, marginTop)
set.setMargin(R.id.about_container, ConstraintSet.TOP, marginTop)
set.applyTo(it)
// ...
}
}
le animatedView représente l’enfant MotionLayout, contenant toutes les vues qui seront animées. le firstSet, secondSet, ThirdSet sont les identifiants du ConstraintSets.
private val firstSet = R.id.first_set
private val secondSet = R.id.second_set
private val thirdSet = R.id.third_set
Ils sont définis dans animated_music_band_item_scene.xml.
Après cela, nous devons définir les données sur des vues animées, définir l’écouteur de transition, démarrer l’animation parent pour masquer RecyclerViewet montrez l’enfant MotionLayout. Voici le code pour cela:
private fun animate(
vhValues: MusicBandAdapter.ViewHolderValues,
musicBandModel: MusicBandModel) {animatedView.also {
// ...
with(binding) {
thumbnail.background =
ContextCompat.getDrawable(this@MusicBandListActivity, musicBandModel.drawableId)
name.text = getString(musicBandModel.name)
tags.text = getString(musicBandModel.tags)
description.text = getString(musicBandModel.shortDescriptionStringRes)
aboutText.text = getString(musicBandModel.aboutStringRes)
it.setTransitionListener(transitionAdapter)
root.transitionToEnd()
it.setTransition(firstSet, secondSet)
it.setTransitionDuration(ANIMATION_DURATION)
it.transitionToState(secondSet)
activeSet = ConstraintSetState.FIRST_TO_SECOND
}
}
}
le activeSet est un ConstraintSetState type qui est une énumération qui nous aide à suivre ConstraintSet sera le suivant ou le précédent.
private enum class ConstraintSetState {
FIRST_TO_SECOND,
SECOND_TO_THIRD,
SECOND_TO_FIRST,
THIRD_TO_SECOND
}
Vous remarquerez que le racine l’animation est démarrée en utilisant le transitionToEnd() méthode qui n’a que deux ConstraintSets → activity_music_band_list_scene.xml. L’animation sur animatedView n’est pas cependant. En effet, nous avons une animation en plusieurs étapes et nous devons définir les transitions manuellement.
Puisqu’il y a beaucoup de code XML dans le fichier MotionScene, que je ne veux pas copier et coller ici, vous pouvez ouvrir animated_music_band_item_scene.xml et vérifiez tout ConstraintSets et Transitions.
Après le première transition (firstSet → secondSet), l’écran ressemble à ceci:
dans le first_set, nous positionnons les vues, définissons le rapport et l’échelle des dimensions des miniatures. L’échelle doit être réinitialisée car nous voulons l’échelle initiale pendant que l’animation s’exécute de la fin au début. L’échelle réelle est appliquée à partir de la position 80 du cadre (définie dans Transition bloquer). Nous masquons également la flèche arrière en définissant son alpha et visibilité valeur. dans le second_set, nous devons redéfinir le type d’échelle pour qu’il ne soit pas perdu. Nous devons également masquer d’autres vues en modifiant leur alpha valeurs.
Lorsque la première transition est terminée, nous sommes immédiatement prêts à démarrer la deuxième transition (secondSet → ThirdSet) dans le onTransitionCompleted rappeler. Il en résulte l’écran suivant:
Nous partons du second_set et, dans le troisième_ensemble, nous rendons les vues visibles tout en contrôlant la situation lorsque l’animation sera exécutée de l’état final à l’état initial. À l’intérieur de Transition bloc, le Sur clic l’action est utilisée pour basculer entre second_set et third_set.
La dernière étape de l’animation est complètement définie dans le scène de mouvement fichier car nous pouvons choisir des actions lorsque l’utilisateur clique sur la vue. Dans notre scénario, nous avons à nouveau un Sur clic action à l’intérieur Transition qui gère le début et l’état final pour nous. Il y a aussi KeyFrameSet élément qui contient le KeyAttribute éléments utilisés pour changer alpha valeurs pour des vues spécifiques pendant la transition. Attribut app: framePosition peut contenir n’importe quelle valeur entre 0 et 100. Une autre classe utile est ImageFilterView qui, dans notre cas, est utilisé pour animer entre deux images avec son fondu enchaîné attribut.
L’écran ressemble maintenant à ceci:
Cet article fournit des informations générales sur MotionLayout et un exemple d’animation avec toutes les pièces réunies. Même s’il est toujours en version bêta, cela ne nous empêche pas de créer de belles animations. Si vous souhaitez en savoir plus sur MotionLayout voici quelques ressources:
J’espère que vous avez appris quelque chose de nouveau dans cet article. N’hésitez pas à poster vos questions ou commentaires ci-dessous ou à me contacter sur denis@arsfutura.co. À votre santé!
Publié à l’origine sur:
Remerciements particuliers à Lea Metlicic, Antonija Golic et Josip Grubeša.