Animaciones básicas en Flutter

Si bien Flutter tiene una enorme cantidad de paquetes sorprendentes para crear efectos de animación para tus aplicaciones, también hay métodos integrados para crear manualmente animaciones más precisas.
Prerrequisitos
Para nuestras animaciones en varias pantallas, supondré que ya sabes cómo crear rutas básicas, para resumir. Puedes revisar la documentación aquí si aún no te sientes cómodo con eso.
Animaciones lineales
Las tres partes principales de nuestras animaciones son ticker
controlar el tiempo, controller
registrar los parámetros como la duración y los valores que queremos cambiar. Antes de que se renderice nuestro widget, en nuestro initState
, podemos configurar nuestro controlador con sus parámetros, establecer su dirección y agregar un detector para restablecer el estado de nuestros widgets con cada cambio.
De manera predeterminada, un controlador cambiará de 0 a 1 en el tiempo que establezcamos para nuestra duración. Podemos imprimirlo controller.value
en nuestro detector para ver que esto sucede. Podemos cambiar nuestros valores de inicio y fin predeterminados configurando las propiedades upperBound
o .lowerBound
principal.dart
class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() = _MyHomePageState();}class _MyHomePageState extends StateMyHomePage with SingleTickerProviderStateMixin { AnimationController controller; void initState() { super.initState(); controller = AnimationController( duration: Duration(seconds: 1), vsync: this); // Links this controller to this widget so it won't run if the parent widget isn't rendered, to save on resources. controller.forward(); controller.addListener(() = setState(() {})); }}
Para usar nuestra animación solo necesitamos configurar lo que queramos, como la opacidad controller.value
.
@override Widget build(BuildContext context) { return Scaffold( body: Center( child: Opacity( opacity: controller.value, child: Container(width: 50, height: 50, color: Colors.red), ), ), ); }
Animaciones curvas
En lugar de animaciones lineales aburridas, podemos usar diferentes variaciones curvas para controlar exactamente cómo cambia nuestro controlador. Para hacer esto, podemos usar CurvedAnimation
una especie de contenedor sobre nuestro controlador original. Este contenedor tomará su padre, nuestro controlador, y la curva que queremos aplicar. Cuando usamos una animación curva, no podemos tener límites inferiores y superiores además de 0 y 1, por lo que cuando la aplicamos podemos simplemente multiplicar su valor. Hay una lista muy extensa de opciones en la documentación.
Otro método útil controller
es addStatusListener
, que nos permitirá aprovechar su ciclo de vida. Nuestro controlador activa un evento completado o descartado cuando su valor alcanza su límite superior o inferior. Podemos usarlo con sus métodos forward
y reverse
para hacer un bucle infinito en nuestra animación.
class _MyHomePageState extends StateMyHomePage with SingleTickerProviderStateMixin { AnimationController controller; Animation animation; void initState() { super.initState(); controller = AnimationController( duration: Duration(seconds: 1), vsync: this); animation = CurvedAnimation(parent: controller, curve: Curves.slowMiddle); controller.forward(); animation.addListener(() = setState(() {})); controller.addStatusListener((status) { if (status == AnimationStatus.completed) controller.reverse(from: 400); else if (status == AnimationStatus.dismissed) controller.forward(); }); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Container( margin: EdgeInsets.only(bottom: animation.value * 400), width: 50, height: 50, color: Colors.red), ), ); }}
Preadolescentes
En lugar de trabajar únicamente con valores numéricos, también podemos trabajar con rangos de otras cosas, como colores, mediante interpolaciones (abreviatura de between). Al igual que con nuestra animación curva, actuará como un contenedor para nuestro controlador o animación y podemos establecer nuestro color en su valor.
principal.dart
class _MyHomePageState extends StateMyHomePage with SingleTickerProviderStateMixin { AnimationController controller; Animation animation; Animation changeColor; void initState() { super.initState(); controller = AnimationController(duration: Duration(seconds: 1), vsync: this); animation = CurvedAnimation(parent: controller, curve: Curves.slowMiddle); changeColor = ColorTween(begin: Colors.red, end: Colors.blue).animate(animation); controller.forward(); animation.addListener(() = setState(() {})); controller.addStatusListener((status) { if (status == AnimationStatus.completed) controller.reverse(from: 400); else if (status == AnimationStatus.dismissed) controller.forward(); }); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Container( margin: EdgeInsets.only(bottom: animation.value * 400), width: 50, height: 50, color: changeColor.value), ), ); }}
Pantalla cruzada
Otra técnica genial es usar el widget Hero cuando queremos una transición entre widgets en diferentes pantallas. Solo tenemos que envolver cada uno en su propio widget Hero con las etiquetas correspondientes. Las etiquetas deben ser únicas y no puede haber más de una en la pantalla en ningún momento.
primera pantalla
Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: Widget[ SizedBox(height: 1), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: Widget[ Hero(tag: 'icon', child: Icon(Icons.add)), ]), Navbar() ]));}
segunda pantalla
Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: Widget[ SizedBox(height: 1), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: Widget[ SizedBox(width: 1), Hero( tag: 'icon', child: Icon(Icons.add, color: Colors.red, size: 75)), ]), Navbar() ]), );}
Conclusión
En la mayoría de las tecnologías web frontend del pasado, las animaciones se dejaban como una idea de último momento, pero el equipo de Flutter hizo un trabajo increíble al tenerlas en cuenta al desarrollar este increíble marco. En realidad, solo hemos arañado la superficie de lo que Flutter es capaz de hacer en términos de animaciones.
Deja una respuesta