← Flutter & Dart

Flutter avanzado

¿Cómo funciona la navegación en Flutter y qué diferencia hay entre `push` y `pushReplacement`?

Ver respuesta — intenta responderla en voz alta primero

Flutter navega con un Navigator que maneja una pila (stack) de rutas. push agrega una pantalla encima de la actual (puedes volver con pop). pushReplacement reemplaza la pantalla actual por otra (no puedes volver a la anterior). También existe la navegación declarativa (Navigator 2.0 y paquetes como go_router) para casos más complejos.

Piensa en la navegación como una pila de cartas: la carta de arriba es la pantalla que ves.

  • push: pones una carta nueva encima. pop la quita y vuelves a la anterior.
  • pushReplacement: cambias la carta de arriba por otra. La anterior desaparece de la pila, así que no hay "regreso".
  • pushNamed: navegas usando nombres de ruta registrados ('/detalle'), útil para centralizar rutas.
  • pop con resultado: al volver puedes devolver un valor a la pantalla anterior.

Para apps con navegación compleja (deep links, web, estado de navegación), se usa el enfoque declarativo con go_router, que es hoy el recomendado por el equipo de Flutter.

import 'package:flutter/material.dart';

// Ir a una pantalla nueva y poder volver
void abrirDetalle(BuildContext context) {
  Navigator.of(context).push(
    MaterialPageRoute(builder: (_) => const Detalle()),
  );
}

// Reemplazar la actual (por ejemplo, tras un login: no quieres volver al login)
void irAlHome(BuildContext context) {
  Navigator.of(context).pushReplacement(
    MaterialPageRoute(builder: (_) => const Home()),
  );
}

// Volver devolviendo un resultado
void volverConDato(BuildContext context) {
  Navigator.of(context).pop("resultado");
}

class Detalle extends StatelessWidget {
  const Detalle({super.key});
  @override
  Widget build(BuildContext context) => const Scaffold();
}

class Home extends StatelessWidget {
  const Home({super.key});
  @override
  Widget build(BuildContext context) => const Scaffold();
}

Usar push cuando debías usar pushReplacement, típicamente tras un login o un splash. Si haces push al home después del login, el usuario puede presionar "atrás" y regresar a la pantalla de login, lo que no tiene sentido. Otro error: intentar pop cuando ya no hay nada debajo en la pila (cerrarías la app sin querer).

"Flutter usa un Navigator que maneja una pila de rutas. push agrega una pantalla encima y puedo volver con pop; pushReplacement cambia la pantalla actual por otra sin dejar regreso, que es lo que uso después de un login o un splash. Puedo navegar por nombres con pushNamed y devolver resultados con pop. Para navegación compleja, deep links o web, uso el enfoque declarativo con go_router, que es el recomendado actualmente."

Reto rápido

Después de un login exitoso quieres llevar al usuario al home y que el botón "atrás" no lo regrese al login. ¿Qué método usas?

Ver respuesta

pushReplacement (o pushReplacementNamed). Reemplaza la pantalla de login por el home en la pila, así que el login desaparece y el botón "atrás" ya no lo regresa. Si quisieras borrar toda la pila anterior (por ejemplo, varias pantallas), usarías pushAndRemoveUntil.