MotionLayout: KeyCycle, KeyTimeCycle y KeyTrigger #AndroidMeetsKotlin
Francisco Manuel López Jurado Colaboraciones 11/01/2019
Google ha hecho los deberes antes de irse de vacaciones y ha sacado el 21 de Diciembre de 2018 la versión “alpha3” de ConstraintLayout v2.0.0 aportando nuevos componentes como son: KeyCycle, KeyTimeCycle y KeyTrigger (entre otros). En los anteriores post sobre MotionLayout (parte 1 y parte 2) has podido ver prácticamente todos los elementos que estaban en la versión “constraint-layout:2.0.0-alpha2” de este componente.
Puesto que está en continua expansión, en este post vas a ver nuevos elementos que dotarán a tus animaciones de una mayor personalización y control. Sin más, ¡manos a la obra!
Cambios a la hora de definir los ConstraintSet en los MotionScene
Esta nueva release trae una ventaja muy importante, adiós al código repetido entre los ConstraintSet de inicio y fin. Es decir, en la versión “alpha2” los elementos “Constraint” tenían que contener TODOS los atributos definidos en una vista ya que serían todos reemplazados cuando se aplicaba las de la animación de fin. Ahora, sólo bastaría con agregar aquellas áreas o elementos específicos que se van a modificar, por tanto, podemos añadirlas dentro del tag “Constraint” como:
- “<Layout>”. Se trata de todas las constraints para las vistas.
- “<PropertySet>”. Cambios de propiedades como visibilidad, alfa y progreso.
- “<Transform>”. Cambios de escala, traslaciones, rotaciones, pivotes, elevaciones, etc.
- “<Motion>”: formas, arcos, etc.
Para que lo entiendas mejor, vamos a ver el cambio que supone esto en las ConstraintSet de fin para la vista “b” que teníamos en la parte 2 de esta sucesión de posts.
Tienes todo el código de este layout de forma simplificada en el siguiente enlace.
Cambios en el tag OnClick
- Soporta múltiples “OnClick” por escena.
- Se ha modificado motion:mode por motion:clickAction.
KeyTimeCycle
Se trata de un elemento que permite definir un ciclo impulsado por el tiempo en lugar de por el progreso de la transición.
KeyCycle
Su función es controlar las oscilaciones del objeto que se anima. Por tanto, al usar un KeyCycle junto con los KeyPosition, puedes agregar todas las oscilaciones que necesites a la animación. Su creación es similar a los otros componentes que has visto, debes proporcionar nuevamente el ID del elemento de destino, una posición a lo largo de la línea de tiempo y el valor deseado de la propiedad que debe oscilar hacia adelante y hacia atrás. También puedes configurar un oscilador proporcionando detalles como la forma de onda a usar y el período de la misma. Las propiedades son:
- “target”. Id de la vista.
- “framePosition”. El punto en el que se aplicará la oscilación, desde 0 a 100.
- Atributos de vista generales, éstos están definidos en el siguiente enlace.
- “waveShape”. La forma de la onda a generar. Valores posibles: {sin | square | triangle | sawtooth | reverseSawtooth | cos | bounce}.
- “wavePeriod”. El número de ciclos que se repetirá la onda.
- “waveOffset”. Valor del “offset” que se le añadirá al atributo.
- “transitionPathRotate”. Ciclos aplicados a la rotación en relación con la ruta que recorre la vista.
- “progress”.Llama al método “setProgress” de la vista.
- Todos el listado de <CustomAttribute> como has visto en los otros componentes.
Si tienes la animación que se indica en el siguiente gif (Sin KeyCycle) y queremos añadirle un KeyCycle que cambie su rotación en 90º mediante una onda (de tipo “sin”) en su instante 50, ésta quedaría de la siguiente forma:
El código que tendrás que añadir será el siguiente:
KeyTrigger
Añade un elemento que puede activar el retorno de eventos en función del progreso de la animación actual. Éste evento podrá ser capturado en el método onTransitionTrigger de TransitionListener.
¡Bonus! TransitionListener
Además, como elemento muy interesante, vas a poder conocer los eventos (callbacks) que tiene TransitionListener ya que en muchas ocasiones puedes necesitar saber cuándo acaba o empieza la animación para realizar seguidamente otra acción. Los métodos que nos encontramos son los siguientes:
- onTransitionTrigger(view: MotionLayout?, p1: Int, p2: Boolean, progress: Float). Se lanza a raíz de los KeyTriggers configurados en la misma.
- onTransitionStarted(view: MotionLayout?, startId: Int, endId: Int). Es llamado cuando comienza la animación.
- onTransitionChange(view: MotionLayout?, startId: Int, endId: Int, progress: Float). Este evento es llamado cada vez que se produce un cambio en la animación.
- onTransitionCompleted(view: MotionLayout?, currentId: Int). Éste, por el contrario, se llama cuando la animación se ha completado, ya sea de inicio o fin.
En resumidas cuentas, la nueva versión de MotionLayout trae nuevas características que serán muy útiles a la hora de realizar tus animaciones. Sin embargo, aún te encontrarás con poca documentación de la misma y errores propios de una versión alpha. Puedes encontrar información de los cambios de esta nueva versión en el siguiente enlace y siempre podrás encontrar toda la información relativa a MotionLayout en el siguiente enlace.