Navegación entre Pantallas en Flutter

La navegación en Flutter es como cambiar de una página a otra en tu app. Es súper fácil una vez que entiendes los conceptos básicos.

  Qué necesitas saber

  • Navigator.push(): Ir a una nueva pantalla
  • Navigator.pop(): Volver a la pantalla anterior
  • MaterialPageRoute: El “camino” para llegar a la nueva pantalla

1Estructura básica de una pantalla

Pantallas en Flutter son widgets que representan una única vista en tu app. Cada pantalla tiene su propia clase y su propio método build().

dart
import 'package:flutter/material.dart';

class MiPantalla extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Mi Pantalla'),
    ),
    body: Center(
      child: Text('¡Hola desde mi pantalla!'),
    ),
  );
}
}
2Ejemplo completo: Dos pantallas

Pantalla Principal (Home)

Aquí tienes la pantalla principal de tu app. Cuando se abre, muestra un botón que, al ser presionado, navega a la segunda pantalla.

dart
import 'package:flutter/material.dart';

class PantallaPrincipal extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Pantalla Principal'),
      backgroundColor: Colors.blue,
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            '¡Bienvenido!',
            style: TextStyle(fontSize: 24),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {
              // Navegar a la segunda pantalla
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => SegundaPantalla(),
                ),
              );
            },
            child: Text('Ir a Segunda Pantalla'),
          ),
        ],
      ),
    ),
  );
}
}

Segunda Pantalla

Aquí tienes la segunda pantalla de tu app. Cuando se abre, muestra un botón que, al ser presionado, vuelve a la pantalla principal.

dart
class SegundaPantalla extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Segunda Pantalla'),
      backgroundColor: Colors.green,
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            '¡Estás en la segunda pantalla!',
            style: TextStyle(fontSize: 20),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {
              // Volver a la pantalla anterior
              Navigator.pop(context);
            },
            child: Text('Volver Atrás'),
          ),
        ],
      ),
    ),
  );
}
}
3Configurar en main.dart

El archivo main.dart es el punto de entrada de tu app. Asegúrate de configurar la MaterialApp con la PantallaPrincipal como la pantalla inicial.

dart
import 'package:flutter/material.dart';

void main() {
runApp(MiApp());
}

class MiApp extends StatelessWidget {

Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Navegación Flutter',
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: PantallaPrincipal(), // Pantalla inicial
  );
}
}
4Pasar datos entre pantallas

Enviar datos a la nueva pantalla

Aquí tienes un ejemplo de cómo enviar datos de una pantalla a otra. En la pantalla que envía, cuando se presiona el botón, se navega a la PantallaConDatos y se pasa el nombre y la edad.

dart
// En la pantalla que envía
ElevatedButton(
onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => PantallaConDatos(
        nombre: 'Juan',
        edad: 25,
      ),
    ),
  );
},
child: Text('Enviar Datos'),
)

Recibir datos en la nueva pantalla

dart
class PantallaConDatos extends StatelessWidget {
final String nombre;
final int edad;

// Constructor que recibe los datos
PantallaConDatos({required this.nombre, required this.edad});


Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Datos Recibidos')),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('Nombre: $nombre', style: TextStyle(fontSize: 20)),
          Text('Edad: $edad años', style: TextStyle(fontSize: 20)),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Volver'),
          ),
        ],
      ),
    ),
  );
}
}
5Navegación con rutas nombradas

Definir rutas en main.dart

En este ejemplo, se definen tres rutas: /, /segunda, y /tercera. La ruta inicial es /, que se mapea a la PantallaPrincipal.

dart
class MiApp extends StatelessWidget {

Widget build(BuildContext context) {
  return MaterialApp(
    title: 'App con Rutas',
    initialRoute: '/', // Ruta inicial
    routes: {
      '/': (context) => PantallaPrincipal(),
      '/segunda': (context) => SegundaPantalla(),
      '/tercera': (context) => TerceraPantalla(),
    },
  );
}
}

Para navegar a una ruta nombrada, como /segunda, puedes usar Navigator.pushNamed(context, '/segunda'). Esto navega a la SegundaPantalla.

dart
// Ir a una ruta nombrada
ElevatedButton(
onPressed: () {
  Navigator.pushNamed(context, '/segunda');
},
child: Text('Ir a Segunda'),
)

// Volver atrás
ElevatedButton(
onPressed: () {
  Navigator.pop(context);
},
child: Text('Volver'),
)
6Ejemplo práctico: App de 3 pantallas
dart
import 'package:flutter/material.dart';

void main() => runApp(MiApp());

class MiApp extends StatelessWidget {

Widget build(BuildContext context) {
  return MaterialApp(
    home: Inicio(),
  );
}
}

class Inicio extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Inicio')),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => Perfil()),
            ),
            child: Text('Ver Perfil'),
          ),
          SizedBox(height: 10),
          ElevatedButton(
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => Configuracion()),
            ),
            child: Text('Configuración'),
          ),
        ],
      ),
    ),
  );
}
}

class Perfil extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Perfil')),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('Mi Perfil', style: TextStyle(fontSize: 24)),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Volver al Inicio'),
          ),
        ],
      ),
    ),
  );
}
}

class Configuracion extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Configuración')),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('Configuración', style: TextStyle(fontSize: 24)),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Volver al Inicio'),
          ),
        ],
      ),
    ),
  );
}
}

Conceptos clave explicados


  Nota

🎯 Navigator.push()

  • ¿Qué hace? Lleva a una nueva pantalla
  • ¿Cuándo usarlo? Cuando quieres ir hacia adelante
  • Resultado: Agrega la nueva pantalla encima de la actual

  Nota

  • ¿Qué hace? Vuelve a la pantalla anterior
  • ¿Cuándo usarlo? Cuando quieres regresar
  • Resultado: Quita la pantalla actual y muestra la anterior

Consejos importantes


  Nota

Buenas prácticas

  • Siempre usa Scaffold en tus pantallas
  • El AppBar automáticamente agrega el botón “atrás”
  • Usa nombres descriptivos para tus pantallas

🚀 Cuándo usar cada método

  • Navigator.push(): Para ir a pantallas nuevas
  • Navigator.pop(): Para volver atrás
  • Rutas nombradas: Para apps con muchas pantallas