Kodokon kodokon.com

Naviguer entre écrans avec Navigator

Empilez et dépilez des écrans avec Navigator.push et pop, transmettez des données par constructeur et récupérez un résultat au retour.

8 min · 3 questions

Ouvrir cette leçon dans Kodokon

Flutter gère vos écrans comme une pile (stack) : Navigator.push pose un nouvel écran au sommet, Navigator.pop retire celui du dessus et révèle le précédent. Chaque écran est une route, et MaterialPageRoute fournit la transition native de la plateforme. Le bouton retour d'Android appelle pop pour vous, sans aucun code.

DART
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('Accueil')),
      body: Center(
        child: FilledButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) {
                  return const DetailScreen(
                    productName: 'Casque audio',
                  );
                },
              ),
            );
          },
          child: const Text('Voir le produit'),
        ),
      ),
    );
  }
}
push empile DetailScreen (défini ci-dessous) sur l'écran courant.

Pour transmettre des données à l'écran suivant, pas de mécanisme magique : l'écran de destination est un widget comme un autre, il reçoit ses données par son constructeur. C'est typé, explicite, et le compilateur vous rattrape si un champ manque. Notez que l'AppBar de l'écran poussé affiche le bouton retour sans que vous n'écriviez rien.

DART
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('Ajouter au panier'),
        ),
      ),
    );
  }
}
pop ferme l'écran et renvoie une valeur à l'appelant.

Navigator.push renvoie un Future qui se complète quand l'écran est fermé, avec la valeur passée à pop. Vous pouvez donc attendre le résultat d'un écran : une confirmation, un élément choisi dans une liste, un formulaire rempli. Le type générique push<bool> documente ce que vous attendez en retour.

DART
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: 'Casque audio',
        );
      },
    ),
  );
  if (!context.mounted) return;
  final message = (added ?? false)
      ? 'Produit ajouté au panier'
      : 'Aucun produit ajouté';
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text(message)),
  );
}
Le Future de push se complète à la fermeture de l'écran.

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Comment Navigator organise-t-il les écrans ?
    • Comme une file : premier arrivé, premier affiché
    • Comme une pile : le dernier écran poussé s'affiche au-dessus
    • Comme un arbre de widgets parallèle
    • Comme une grille d'écrans
  2. Quelle est la manière idiomatique de transmettre des données à l'écran suivant ?
    • Par une variable globale
    • Via le constructeur du widget de destination
    • En les écrivant sur le disque
    • Navigator ne permet pas de passer des données
  3. Que fait Navigator.pop(context, true) ?
    • Il ouvre un nouvel écran nommé « true »
    • Il ferme tous les écrans de la pile
    • Il ferme l'écran courant et renvoie true au push qui attend