En este tema, aprenderemos los conceptos fundamentales de la navegación en Flutter. La navegación es un aspecto crucial en el desarrollo de aplicaciones móviles, ya que permite a los usuarios moverse entre diferentes pantallas o vistas dentro de la aplicación.
Contenidos
Introducción a la Navegación
En Flutter, la navegación se maneja principalmente a través del widget Navigator
. Este widget gestiona una pila de rutas, donde cada ruta representa una pantalla o vista en la aplicación. La navegación implica empujar (push) y sacar (pop) rutas de esta pila.
Navegación con Navigator
El widget Navigator
proporciona varios métodos para manejar la navegación:
Navigator.push
: Empuja una nueva ruta a la pila de navegación.Navigator.pop
: Saca la ruta superior de la pila de navegación.Navigator.pushReplacement
: Reemplaza la ruta actual con una nueva ruta.Navigator.pushNamed
: Empuja una nueva ruta usando un nombre predefinido.
Ejemplo de Navigator.push
y Navigator.pop
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: FirstScreen(), ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First Screen'), ), body: Center( child: ElevatedButton( child: Text('Go to Second Screen'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondScreen()), ); }, ), ), ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: ElevatedButton( child: Text('Go Back'), onPressed: () { Navigator.pop(context); }, ), ), ); } }
Explicación del Código
MyApp
: Es el widget principal que configura la aplicación conMaterialApp
y estableceFirstScreen
como la pantalla inicial.FirstScreen
: Contiene un botón que, al ser presionado, empujaSecondScreen
a la pila de navegación usandoNavigator.push
.SecondScreen
: Contiene un botón que, al ser presionado, saca la ruta superior de la pila de navegación usandoNavigator.pop
, volviendo aFirstScreen
.
Navegación con Rutas
Flutter permite definir rutas nombradas para facilitar la navegación. Esto es especialmente útil en aplicaciones más grandes con muchas pantallas.
Definición de Rutas
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => FirstScreen(), '/second': (context) => SecondScreen(), }, ); } } class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First Screen'), ), body: Center( child: ElevatedButton( child: Text('Go to Second Screen'), onPressed: () { Navigator.pushNamed(context, '/second'); }, ), ), ); } } class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: ElevatedButton( child: Text('Go Back'), onPressed: () { Navigator.pop(context); }, ), ), ); } }
Explicación del Código
initialRoute
: Define la ruta inicial de la aplicación.routes
: Mapa de rutas nombradas a sus correspondientes widgets.Navigator.pushNamed
: Navega a una ruta usando su nombre.
Ejemplo Práctico
Vamos a crear una aplicación simple con tres pantallas: Home, About y Contact. Usaremos rutas nombradas para la navegación.
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => HomeScreen(), '/about': (context) => AboutScreen(), '/contact': (context) => ContactScreen(), }, ); } } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home Screen'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( child: Text('Go to About'), onPressed: () { Navigator.pushNamed(context, '/about'); }, ), ElevatedButton( child: Text('Go to Contact'), onPressed: () { Navigator.pushNamed(context, '/contact'); }, ), ], ), ), ); } } class AboutScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('About Screen'), ), body: Center( child: ElevatedButton( child: Text('Go Back'), onPressed: () { Navigator.pop(context); }, ), ), ); } } class ContactScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Contact Screen'), ), body: Center( child: ElevatedButton( child: Text('Go Back'), onPressed: () { Navigator.pop(context); }, ), ), ); } }
Ejercicios Prácticos
Ejercicio 1: Añadir una Nueva Pantalla
- Añade una nueva pantalla llamada
ProfileScreen
. - Define una ruta nombrada para
ProfileScreen
. - Añade un botón en
HomeScreen
que navegue aProfileScreen
.
Solución
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => HomeScreen(), '/about': (context) => AboutScreen(), '/contact': (context) => ContactScreen(), '/profile': (context) => ProfileScreen(), // Nueva ruta }, ); } } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home Screen'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( child: Text('Go to About'), onPressed: () { Navigator.pushNamed(context, '/about'); }, ), ElevatedButton( child: Text('Go to Contact'), onPressed: () { Navigator.pushNamed(context, '/contact'); }, ), ElevatedButton( child: Text('Go to Profile'), // Nuevo botón onPressed: () { Navigator.pushNamed(context, '/profile'); }, ), ], ), ), ); } } class ProfileScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Profile Screen'), ), body: Center( child: ElevatedButton( child: Text('Go Back'), onPressed: () { Navigator.pop(context); }, ), ), ); } }
Conclusión
En esta lección, hemos aprendido los conceptos básicos de la navegación en Flutter utilizando el widget Navigator
y rutas nombradas. La navegación es esencial para crear aplicaciones móviles interactivas y bien estructuradas. En el próximo tema, exploraremos cómo pasar datos entre pantallas, lo cual es crucial para aplicaciones más complejas.
¡Sigue practicando y experimentando con la navegación en Flutter para dominar estos conceptos!
Curso de Desarrollo con Flutter
Módulo 1: Introducción a Flutter
- ¿Qué es Flutter?
- Configuración del Entorno de Desarrollo
- Entendiendo la Arquitectura de Flutter
- Creando Tu Primera App con Flutter
Módulo 2: Conceptos Básicos de Programación en Dart
- Introducción a Dart
- Variables y Tipos de Datos
- Sentencias de Control de Flujo
- Funciones y Métodos
- Programación Orientada a Objetos en Dart
Módulo 3: Widgets en Flutter
- Introducción a los Widgets
- Widgets Stateless vs Stateful
- Widgets Básicos
- Widgets de Diseño
- Widgets de Entrada y Formularios
Módulo 4: Gestión de Estado
Módulo 5: Navegación y Enrutamiento
- Introducción a la Navegación
- Navegación Básica
- Rutas Nombradas
- Pasando Datos Entre Pantallas
- Deep Linking
Módulo 6: Redes y APIs
- Obteniendo Datos de Internet
- Parseo de Datos JSON
- Manejo de Errores de Red
- Usando APIs REST
- Integración con GraphQL
Módulo 7: Persistencia y Almacenamiento
- Introducción a la Persistencia
- Preferencias Compartidas
- Almacenamiento de Archivos
- Base de Datos SQLite
- Usando Hive para Almacenamiento Local
Módulo 8: Conceptos Avanzados de Flutter
- Animaciones en Flutter
- Custom Paint y Canvas
- Canales de Plataforma
- Isolates y Concurrencia
- Optimización de Rendimiento
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias
- Pruebas de Widgets
- Pruebas de Integración
- Técnicas de Depuración
Módulo 10: Despliegue y Mantenimiento
- Preparación para el Lanzamiento
- Construcción para iOS
- Construcción para Android
- Integración Continua/Despliegue Continuo (CI/CD)
- Mantenimiento y Actualización de Tu App