Apila y desapila pantallas con Navigator.push y pop, pasa datos a través de los constructores y recupera un resultado cuando la pantalla se cierra.
Abrir esta lección en KodokonFlutter gestiona tus pantallas como una pila: Navigator.push coloca una nueva pantalla encima, Navigator.pop retira la de arriba y revela la anterior. Cada pantalla es una ruta, y MaterialPageRoute proporciona la transición nativa de la plataforma. El botón de retroceso de Android invoca pop por ti, sin una sola línea de código.
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: FilledButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const DetailScreen(
productName: 'Headphones',
);
},
),
);
},
child: const Text('View product'),
),
),
);
}
}Para pasar datos a la siguiente pantalla, no hay ningún mecanismo mágico: la pantalla de destino es un widget como cualquier otro, y recibe sus datos a través de su constructor. Es tipado, explícito, y el compilador te avisa si falta un campo. Ten en cuenta que la AppBar de la pantalla apilada muestra el botón de retroceso sin que escribas nada.
import 'package:flutter/material.dart';
class DetailScreen extends StatelessWidget {
const DetailScreen({
super.key,
required this.productName,
});
final String productName;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(productName)),
body: Center(
child: FilledButton(
onPressed: () {
Navigator.pop(context, true);
},
child: const Text('Add to cart'),
),
),
);
}
}Navigator.push devuelve un Future que se completa cuando la pantalla se cierra, con el valor pasado a pop. Por lo tanto, puedes esperar el resultado de una pantalla: una confirmación, un elemento elegido de una lista, un formulario rellenado. El tipo genérico push<bool> documenta lo que esperas recibir de vuelta.
import 'package:flutter/material.dart';
Future<void> openDetail(BuildContext context) async {
final added = await Navigator.push<bool>(
context,
MaterialPageRoute<bool>(
builder: (context) {
return const DetailScreen(
productName: 'Headphones',
);
},
),
);
if (!context.mounted) return;
final message = (added ?? false)
? 'Product added to cart'
: 'No product added';
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}