Supongamos que tienes que hacer una aplicación con Flutter, y el diseño deseado incluye animaciones. Lo primero es valorar la viabilidad y el esfuerzo en hacerlas. Es decir, si Flutter las soporta y, en tal caso, qué componentes Flutter utilizar.

Si visitamos la documentación oficial de Flutter sobre animaciones, veremos cantidad de recursos y de información. En mi opinión, la información es sobrecogedora de inicio. Y sobre todo asusta el diagrama de decisión de Emily Fortuna (una de las predicadoras de Flutter).

Con este post pretendemos simplificar el aterrizaje a las animaciones con Flutter. Respondiendo a unas sencillas preguntas podemos encontrar los recursos de Flutter que se adaptan a lo que queremos.

Animaciones en Flutter 1

1 Dibujito moviéndose o widget mutando en alguna propiedad

La primera pregunta que tenemos que hacernos es si lo que queremos es una animación de dibujitos moviéndose (como sprites de videojuegos) o simplemente está basada en widgets de Flutter cambiando de color, posición, etc.

Las animaciones basadas en dibujos incluyen transformaciones que son bastante complejas para expresarlas puramente en código. En estos casos puedes acabar de leer este post, porque ya aquí te remitimos a frameworks como Rive y Lottie y exportar dichas animaciones a Flutter utilizando los paquetes rive y lottie respectivamente. Véanse dos ejemplos:

Por otro lado, las animaciones que podemos codificar son aquellas enfocadas en los widgets, en mutar alguna de sus propiedades. Al estar basadas en layouts estándar y en cambiar cosas como colores, posiciones o formas, suelen ser más simples. Y es de este tipo de animaciones de las que vamos a hablar el resto de este post.

2 Explícita o implícita

Flutter divide las animaciones basadas en código en dos clases: implícitas y explícitas.

Las animaciones implícitas, según la documentación de Flutter, son las que se basan en establecer un valor inicial de una propiedad de un Widget, establecer el valor final y Flutter se encarga de hacer las animaciones para ir de un valor a otro (el proceso de calcular los valores de animación entre una posición inicial y una posición final se llama interpolación). Son el mejor punto de partida para empezar con animaciones en Flutter. Un ejemplo transicionando opacity para revelar los detalles de una foto:

Main.dart (extracto)

class _FadeInDemoState extends State<FadeInDemo> {
 double opacity = 0.0;

 @override
 Widget build(BuildContext context) {
   return Column(children: <Widget>[
     Image.network(owlUrl),
     TextButton(
       child: const Text(
         'Show Details',
         style: TextStyle(color: Colors.blueAccent),
       ),
       onPressed: () => setState(() {
         opacity = 1;
       }),
     ),
     AnimatedOpacity(
       duration: const Duration(seconds: 2),
       opacity: opacity,
       child: Column(
         children: const [
           Text('Type: Owl'),
           Text('Age: 39'),
           Text('Employment: None'),
         ],
       ),
     )
   ]);
 }
}

Para reconocer si lo que queremos es una animación explícita basta con hacernos estas tres preguntas:

Si la respuesta es afirmativa en alguna de esas preguntas, ya puedes decir que lo que quieres es una animación explícita. Requieren implementar un controller AnimationController que define cuándo y cómo se hace la animación.

Un ejemplo con la propiedad opacity sería utilizar una transición en bucle del logo de Flutter:

Main.dart (extracto)

class _MyStatefulWidgetState extends State<MyStatefulWidget>
   with TickerProviderStateMixin {
 late final AnimationController _controller = AnimationController(
   duration: const Duration(seconds: 2),
   vsync: this,
 )..repeat(reverse: true);
 late final Animation<double> _animation = CurvedAnimation(
   parent: _controller,
   curve: Curves.easeIn,
 );

 @override
 void dispose() {
   _controller.dispose();
   super.dispose();
 }

 @override
 Widget build(BuildContext context) {
   return Container(
     color: Colors.white,
     child: FadeTransition(
       opacity: _animation,
       child: const Padding(padding: EdgeInsets.all(8), child: FlutterLogo()),
     ),
   );
 }
}

En realidad vemos que lo que Flutter llama animaciones explícitas es simplemente un nivel de control más avanzado sobre la transición, donde podemos controlar aspectos, como por ejemplo si queremos que la animación haga un reverse o qué curva de interpolación de valores usamos.

3 Consulta el catálogo

Ya sabemos que vamos a hacer una animación basada en código, ya sea explícita o implícita. El catálogo de animaciones de Flutter contiene varios built-in widgets tanto para animaciones implícitas como explícitas.

Las built-in implícitas siguen la regla de nombre de Animation<MiPropiedad> donde MiPropiedad es la propiedad de un widget que queremos animar de un valor incial a otro final. Mientras que en las built-in explícitas el patrón a buscar es <Efecto>Transition dónde Efecto se refiere al efecto visual que genera una transición sobre esa propiedad que queremos animar. Véase algunos ejemplos:

Propiedad Implicit built-in widget Explicit built-in widget
opacity AnimatedOpacity * FadeTransition *
align AnimatedAlign SlideTransition
position AnimatedPosition PositionedTransition

En el caso de no encontrar el widget para la animación que necesitas, entonces siempre te puedes crear una custom con TweenAnimationBuilder, AnimatedWidget o AnimatedBuilder.

En este punto, si tienes respuestas a las preguntas anteriores, ya deberías tener claro qué herramientas del API core de Flutter te pueden ayudar a fabricar tu animación. Seguidamente, vamos a tratar otras consideraciones que te pueden ayudar.

4 Tween vs físicas

Viene bien aclarar si la transición que queremos hacer es de tipo Tween o basada en leyes físicas.

Tween es la abreviatura de in-betweening. Las animaciones Tween son aquellas donde los puntos iniciales y finales están definidos, así como el timeline y la curva que define el timing y la velocidad de la transición. Con esa información Flutter fabrica la interpolación entre los valores. Todos los ejemplos mostrados hasta el momento son de este tipo.

Las animaciones basadas en leyes físicas modelan el movimiento de objetos para recrear el comportamiento del mundo real. Por ejemplo, cuando se lanza una pelota, el lugar y el momento en que cae depende de la velocidad a la que se ha lanzado y de la distancia a la que se encuentra del suelo. Del mismo modo, dejar caer una pelota atada a un muelle cae (y rebota) de forma diferente a dejar caer una pelota atada a una cuerda.

En estos casos AnimationController tiene un método animateWith que acepta clases de tipo Simulation. Son clases que implementan modelos físicos. Los disponibles se pueden ver en: https://api.flutter.dev/flutter/physics/physics-library.html

El siguiente ejemplo utiliza SpringSimulation para modelar el comportamiento de una partícula unida a un muelle siguiendo la ley de Hooke:

Precocinados Flutter

La documentación oficial de Flutter va aún más allá y nos ayuda con recetas para los casos más típicos a los que nos retan desde UX:

Animaciones sobre listas al añadir/borrar elementos

Transiciones entre pantallas

Transiciones sobre elementos compartidos (Hero animations)

Animaciones solapadas (staggered)

Parece que muchas de estas aplicaciones las han recopilado en la librería animations donde parecen tener ejemplos más pulidos.

Conclusiones

Investigando para hacer este post, se nota que Google mantiene Flutter como una apuesta en su oferta de desarrollos nativos. La documentación (casi siempre) y la cantidad de videos facilitan bastante la adopción de esta plataforma. Y ojo que empieza a comer terreno a React Native:

Animaciones en Flutter 2

Os propongo como conclusión simplificar el complicado diagrama de Emily Fortuna en este árbol de decisión que cubre el 90% de los casos de animaciones que se te vayan a presentar:

Animaciones en Flutter 3

Espero con este post haberos ayudado a perder el miedo a desarrollar animaciones con Flutter. Y estaré encantado de recibir vuestras experiencias, opiniones y preguntas.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.