Animar una transición de ruta de página
Cómo animar de una página a otra.
Un lenguaje de diseño, como Material, define comportamientos estándar al
realizar transiciones entre rutas (o pantallas). A veces, sin embargo, una transición
personalizada entre pantallas puede hacer que una aplicación sea más única. Para ayudar,
PageRouteBuilder
proporciona un objeto Animation.
Esta Animation se puede usar con objetos Tween
y
Curve
para personalizar la animación de transición.
Esta receta muestra cómo realizar la transición entre
rutas animando la nueva ruta a la vista desde
la parte inferior de la pantalla.
Para crear una transición de ruta de página personalizada, esta receta utiliza los siguientes pasos:
- Configurar un PageRouteBuilder
- Crear un
Tween - Añadir un
AnimatedWidget - Usar un
CurveTween - Combinar los dos
Tweens
1. Configurar un PageRouteBuilder
#Para empezar, usa un PageRouteBuilder
para crear una Route.
PageRouteBuilder tiene dos retrollamadas (callbacks), una para construir el contenido de la ruta
(pageBuilder), y otra para construir la transición de la ruta (transitionsBuilder).
El siguiente ejemplo crea dos rutas: una ruta de inicio con un botón "Go!", y una segunda ruta titulada "Page 2".
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: Page1()));
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(_createRoute());
},
child: const Text('Go!'),
),
),
);
}
}
Route<void> _createRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return child;
},
);
}
class Page2 extends StatelessWidget {
const Page2({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: const Center(child: Text('Page 2')),
);
}
}
2. Crear un Tween
#Para hacer que la nueva página se anime desde la parte inferior, debe animarse de
Offset(0, 1) a Offset(0, 0) (normalmente definido usando el constructor
Offset.zero). En este caso, Offset es un vector 2D para el
Widget FractionalTranslation.
Establecer el argumento dy a 1 representa una traducción vertical de una
altura completa de la página.
La retrollamada (callback) transitionsBuilder tiene un parámetro animation. Es un
Animation<double> que produce valores entre 0 y 1. Convierte el
Animation<double> en un Animation<Offset> usando un Tween:
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return child;
},
3. Usar un AnimatedWidget
#Flutter tiene un conjunto de Widgets que extienden de AnimatedWidget
que se reconstruyen a sí mismos cuando cambia el valor de la animación. Por ejemplo,
SlideTransition toma un Animation<Offset> y traslada a su hijo (usando un
Widget FractionalTranslation) cada vez que el valor de la animación cambia.
Devolver un SlideTransition
con el Animation<Offset> y el Widget hijo:
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return SlideTransition(position: offsetAnimation, child: child);
},
4. Usar un CurveTween
#Flutter proporciona una selección de curvas de atenuación (easing curves) que
ajustan el ritmo de la animación a lo largo del tiempo.
La clase Curves
proporciona un conjunto predefinido de curvas de uso común.
Por ejemplo, Curves.easeOut
hace que la animación comience rápido y termine lentamente.
Para usar una Curve, crea un nuevo CurveTween
y pásale una Curve:
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
Este nuevo Tween todavía produce valores de 0 a 1. En el siguiente paso, se
combinará con el Tween<Offset> del paso 2.
5. Combinar los dos Tweens
#Para combinar los tweens,
usa chain():
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
Luego usa este tween pasándolo a animation.drive(). Esto crea un nuevo
Animation<Offset> que se puede dar al Widget SlideTransition:
return SlideTransition(position: animation.drive(tween), child: child);
Este nuevo Tween (o Animatable) produce valores de Offset evaluando primero el
CurveTween, luego evaluando el Tween<Offset>. Cuando se ejecuta la animación, los
valores se calculan en este orden:
- La animación (proporcionada a la retrollamada transitionsBuilder) produce valores de 0 a 1.
- El CurveTween mapea esos valores a nuevos valores entre 0 y 1 basados en su curva.
- El
Tween<Offset>mapea los valoresdoublea valoresOffset.
Otra forma de crear un Animation<Offset> con una curva de atenuación es usar un
CurvedAnimation:
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
final tween = Tween(begin: begin, end: end);
final curvedAnimation = CurvedAnimation(parent: animation, curve: curve);
return SlideTransition(
position: tween.animate(curvedAnimation),
child: child,
);
}
Ejemplo interactivo
#A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-11. Ver código fuente oreportar un problema.