Saltar al contenido principal

Introducción a las animaciones

Cómo realizar animaciones en Flutter.

Las animaciones bien diseñadas hacen que una UI se sienta más intuitiva, contribuyen al aspecto impecable y refinado de una aplicación pulida, y mejoran la experiencia del usuario. El soporte de animaciones de Flutter facilita la implementación de una variedad de tipos de animación. Muchos widgets, especialmente los widgets Material, vienen con los efectos de movimiento estándar definidos en su especificación de diseño, pero también es posible personalizar estos efectos.

Elegir un enfoque

#

Existen diferentes enfoques que puedes adoptar al crear animaciones en Flutter. ¿Qué enfoque es el adecuado para ti? Para ayudarte a decidir, echa un vistazo al video, ¿Cómo elegir qué widget de animación de Flutter es el adecuado para ti? (También publicado como un artículo complementario).

Ver en YouTube en una pestaña nueva: "Cómo elegir qué widget de animación de Flutter es el adecuado para tu caso de uso"

(Para profundizar en el proceso de decisión, mira el video Animaciones en Flutter hechas correctamente , presentado en Flutter Europe).

Como se muestra en el video, el siguiente árbol de decisiones te ayuda a decidir qué enfoque usar al implementar una animación en Flutter:

El árbol de decisiones de animación

Análisis profundo de animaciones

#

Para comprender más a fondo cómo funcionan las animaciones en Flutter, mira Profundización en animaciones. (También publicado como un artículo complementario).

Ver en YouTube en una pestaña nueva: "Profundiza en las animaciones de Flutter"

Animaciones implícitas y explícitas

#

Animaciones implícitas preempaquetadas

#

Si una animación implícita preempaquetada (la animación más fácil de implementar) se adapta a tus necesidades, mira Conceptos básicos de animación con animaciones implícitas. (También publicado como un artículo complementario).

Ver en YouTube en una pestaña nueva: "Conceptos básicos de animaciones implícitas en Flutter"

Animaciones implícitas personalizadas

#

Para crear una animación implícita personalizada, mira Creación de tus propias animaciones implícitas personalizadas con TweenAnimationBuilder. (También publicado como un artículo complementario).

Ver en YouTube en una pestaña nueva: "Crea animaciones implícitas personalizadas con TweenAnimationBuilder"

Animaciones explícitas integradas

#

Para crear una animación explícita (donde tú controlas la animación, en lugar de dejar que el framework la controle), tal vez puedas usar una de las clases de animaciones explícitas integradas. Para más información, mira Creación de tus primeras animaciones direccionales con animaciones explícitas integradas. (También publicado como un artículo complementario).

Ver en YouTube en una pestaña nueva: "Crea tus primeras animaciones direccionales con animaciones explícitas integradas"

Animaciones explícitas

#

Si necesitas construir una animación explícita desde cero, mira Creación de animaciones explícitas personalizadas con AnimatedBuilder y AnimatedWidget. (También publicado como un artículo complementario).

Ver en YouTube en una pestaña nueva: "Creando animaciones explícitas personalizadas con AnimatedBuilder y AnimatedWidget"

Tipos de animación

#

En general, las animaciones se basan en tweens o en física. Las siguientes secciones explican qué significan estos términos, y te remiten a recursos donde puedes aprender más.

Animación Tween

#

Abreviatura de in-betweening (intercalado). En una animación tween, se definen los puntos inicial y final, así como una línea de tiempo y una curva que define la temporización y la velocidad de la transición. El framework calcula cómo realizar la transición desde el punto inicial hasta el punto final.

Animación basada en física

#

En la animación basada en física, el movimiento se modela para imitar el comportamiento del mundo real. Cuando lanzas una pelota, por ejemplo, dónde y cuándo aterriza depende de qué tan rápido fue lanzada y a qué distancia estaba del suelo. De manera similar, soltar una pelota unida a un resorte cae (y rebota) de forma diferente a soltar una pelota unida a una cuerda.

Patrones de animación comunes

#

La mayoría de los diseñadores de UX o de movimiento encuentran que ciertos patrones de animación se usan repetidamente al diseñar una UI. Esta sección enumera algunos de los patrones de animación usados comúnmente y te indica dónde aprender más.

Lista o cuadrícula animada

#

Este patrón implica animar la adición o eliminación de elementos de una lista o cuadrícula.

  • Ejemplo de AnimatedList
    Esta demostración, del catálogo de aplicaciones de muestra, muestra cómo animar la adición de un elemento a una lista, o la eliminación de un elemento seleccionado. La lista interna de Dart se sincroniza a medida que el usuario modifica la lista usando los botones más (+) y menos (-).

Transición de elementos compartidos

#

En este patrón, el usuario selecciona un elemento—a menudo una imagen—de la página, y la UI anima el elemento seleccionado a una nueva página con más detalle. En Flutter, puedes implementar fácilmente transiciones de elementos compartidos entre rutas (páginas) usando el widget Hero.

  • Animaciones Hero Cómo crear dos estilos de animaciones Hero:

    • El hero vuela de una página a otra mientras cambia de posición y tamaño.
    • El límite del hero cambia de forma, de un círculo a un cuadrado, a medida que vuela de una página a otra.
  • Consulta también la documentación de la API para las clases Hero, Navigator y PageRoute.

Animación escalonada

#

Animaciones que se dividen en movimientos más pequeños, donde parte del movimiento se retrasa. Las animaciones más pequeñas pueden ser secuenciales, o pueden superponerse parcial o completamente.

Conceptos y clases esenciales de animación

#

El sistema de animación en Flutter se basa en objetos tipados Animation. Los widgets pueden incorporar estas animaciones en sus funciones build directamente leyendo su valor actual y escuchando sus cambios de estado, o pueden usar las animaciones como base de animaciones más elaboradas que pasan a otros widgets.

Animation<double>

#

En Flutter, un objeto Animation no sabe nada sobre lo que está en pantalla. Un Animation es una clase abstracta que comprende su valor actual y su estado (completado o descartado). Uno de los tipos de animación más comúnmente utilizados es Animation<double>.

Un objeto Animation genera secuencialmente números interpolados entre dos valores a lo largo de una determinada duración. La salida de un objeto Animation puede ser lineal, una curva, una función escalonada o cualquier otra asignación que puedas crear. Dependiendo de cómo se controle el objeto Animation, podría ejecutarse a la inversa, o incluso cambiar de dirección en medio.

Las animaciones también pueden interpolar tipos distintos a double, tales como Animation<Color> o Animation<Size>.

Un objeto Animation tiene estado. Su valor actual está siempre disponible en el miembro .value.

Un objeto Animation no sabe nada sobre el renderizado ni sobre las funciones build().

CurvedAnimation

#

Un CurvedAnimation define el progreso de la animación como una curva no lineal.

dart
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn);

CurvedAnimation y AnimationController (descritos en las siguientes secciones) son ambos de tipo Animation<double>, por lo que puedes pasarlos indistintamente. El CurvedAnimation envuelve el objeto que está modificando; no creas una subclase de AnimationController para implementar una curva.

Puedes usar Curves con CurvedAnimation. La clase Curves define muchas curvas utilizadas comúnmente, o puedes crear la tuya propia. Por ejemplo:

dart
import 'dart:math';

class ShakeCurve extends Curve {
  @override
  double transform(double t) => sin(t * pi * 2);
}

Si quieres aplicar una curva de animación a un Tween, considera usar CurveTween.

AnimationController

#

AnimationController es un objeto Animation especial que genera un nuevo valor cada vez que el hardware está listo para un nuevo fotograma (frame). Por defecto, un AnimationController produce linealmente los números de 0.0 a 1.0 durante una duración determinada. Por ejemplo, este código crea un objeto Animation, pero no inicia su ejecución:

dart
controller = AnimationController(
  duration: const Duration(seconds: 2),
  vsync: this,
);

AnimationController deriva de Animation<double>, por lo que se puede usar dondequiera que se necesite un objeto Animation. Sin embargo, el AnimationController tiene métodos adicionales para controlar la animación. Por ejemplo, inicias una animación con el método .forward(). La generación de números está vinculada al refresco de pantalla, por lo que normalmente se generan 60 números por segundo. Después de generar cada número, cada objeto Animation llama a los objetos Listener adjuntos. Para crear una lista de visualización personalizada para cada hijo, consulta RepaintBoundary.

Al crear un AnimationController, le pasas un argumento vsync. La presencia de vsync evita que las animaciones fuera de pantalla consuman recursos innecesarios. Puedes usar tu objeto stateful como vsync añadiendo SingleTickerProviderStateMixin a la definición de la clase. Puedes ver un ejemplo de esto en animate1 en GitHub.

Tween

#

Por defecto, el rango del objeto AnimationController va de 0.0 a 1.0. Si necesitas un rango diferente o un tipo de datos diferente, puedes usar un Tween para configurar una animación para que interpole a un rango o tipo de datos diferente. Por ejemplo, el siguiente Tween va de -200.0 a 0.0:

dart
tween = Tween<double>(begin: -200, end: 0);

Un Tween es un objeto stateless que solo toma begin y end. El único trabajo de un Tween es definir una asignación de un rango de entrada a un rango de salida. El rango de entrada habitualmente es de 0.0 a 1.0, pero eso no es un requisito.

Un Tween hereda de Animatable<T>, no de Animation<T>. Un Animatable, como Animation, no tiene por qué emitir un double. Por ejemplo, ColorTween especifica una progresión entre dos colores.

dart
colorTween = ColorTween(begin: Colors.transparent, end: Colors.black54);

Un objeto Tween no almacena ningún estado. En su lugar, proporciona el método evaluate(Animation<double> animation) que utiliza la función transform para asignar el valor actual de la animación (entre 0.0 y 1.0), al valor real de la animación.

El valor actual del objeto Animation se puede encontrar en el método .value. La función evaluate también realiza algunas tareas de mantenimiento, como garantizar que se devuelvan begin y end cuando los valores de la animación son 0.0 y 1.0, respectivamente.

Tween.animate

#

Para usar un objeto Tween, llama a animate() en el Tween, pasando el objeto controlador. Por ejemplo, el siguiente código genera los valores enteros de 0 a 255 en el transcurso de 500 ms.

dart
AnimationController controller = AnimationController(
  duration: const Duration(milliseconds: 500),
  vsync: this,
);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(controller);

El siguiente ejemplo muestra un controlador, una curva y un Tween:

dart
AnimationController controller = AnimationController(
  duration: const Duration(milliseconds: 500),
  vsync: this,
);
final Animation<double> curve = CurvedAnimation(
  parent: controller,
  curve: Curves.easeOut,
);
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(curve);

Notificaciones de animación

#

Un objeto Animation puede tener Listeners y StatusListeners, definidos con addListener() y addStatusListener(). Se llama a un Listener cada vez que cambia el valor de la animación. El comportamiento más común de un Listener es llamar a setState() para provocar un rebuild. Se llama a un StatusListener cuando una animación comienza, termina, avanza o se revierte, según lo definido por AnimationStatus.

Codelabs, tutoriales y artículos

#

Los siguientes recursos son un buen punto de partida para comenzar a aprender el framework de animación de Flutter. Cada uno de estos documentos muestra cómo escribir código de animación.

  • Codelab de animaciones en Flutter
    Aprende sobre animaciones implícitas y explícitas mientras construyes un juego de trivia de opción múltiple.

  • Tutorial de animaciones
    Explica las clases fundamentales en el paquete de animación de Flutter (controladores, Animatable, curvas, listeners, builders), mientras te guía a través de una progresión de animaciones tween utilizando diferentes aspectos de las API de animación. Este tutorial muestra cómo crear tus propias animaciones explícitas personalizadas.

  • De Cero a Uno con Flutter, parte 1 y parte 2
    Artículos en Medium que muestran cómo crear un gráfico animado usando tweening.

  • Toolkit de juegos casuales
    Un toolkit con plantillas de juegos que contienen ejemplos de cómo usar animaciones en Flutter.

Otros recursos

#

Aprende más sobre las animaciones en Flutter en los siguientes enlaces: