Kodokon kodokon.com

Mit Navigator zwischen Screens navigieren

Lege Screens mit Navigator.push und pop auf den Stapel und wieder herunter, übergib Daten über Konstruktoren und hole ein Ergebnis ab, wenn sich der Screen schließt.

8 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Flutter verwaltet deine Screens als Stapel: Navigator.push legt einen neuen Screen obendrauf, Navigator.pop entfernt den obersten und legt den vorherigen frei. Jeder Screen ist eine Route, und MaterialPageRoute liefert den nativen Übergang der Plattform. Der Zurück-Button von Android ruft pop für dich auf, ohne eine einzige Zeile 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('Home')),
      body: Center(
        child: FilledButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) {
                  return const DetailScreen(
                    productName: 'Headphones',
                  );
                },
              ),
            );
          },
          child: const Text('View product'),
        ),
      ),
    );
  }
}
push legt DetailScreen (weiter unten definiert) über den aktuellen Screen.

Um Daten an den nächsten Screen zu übergeben, gibt es keinen magischen Mechanismus: Der Ziel-Screen ist ein Widget wie jedes andere und erhält seine Daten über seinen Konstruktor. Das ist typisiert, explizit, und der Compiler erwischt dich, wenn ein Feld fehlt. Beachte, dass die AppBar des aufgelegten Screens den Zurück-Button anzeigt, ohne dass du etwas dafür schreibst.

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('Add to cart'),
        ),
      ),
    );
  }
}
pop schließt den Screen und gibt einen Wert an den Aufrufer zurück.

Navigator.push gibt ein Future zurück, das sich abschließt, wenn der Screen geschlossen wird - mit dem Wert, der an pop übergeben wurde. Du kannst also auf das Ergebnis eines Screens warten: eine Bestätigung, ein aus einer Liste gewählter Eintrag, ein ausgefülltes Formular. Der generische Typ push<bool> dokumentiert, was du zurückerwartest.

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: 'Headphones',
        );
      },
    ),
  );
  if (!context.mounted) return;
  final message = (added ?? false)
      ? 'Product added to cart'
      : 'No product added';
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text(message)),
  );
}
Das Future von push schließt sich ab, wenn der Screen geschlossen wird.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Wie organisiert Navigator die Screens?
    • Als Warteschlange: zuerst hinein, zuerst angezeigt
    • Als Stapel: der zuletzt aufgelegte Screen wird oben angezeigt
    • Als parallelen Widget-Baum
    • Als Raster von Screens
  2. Wie übergibt man Daten idiomatisch an den nächsten Screen?
    • Über eine globale Variable
    • Über den Konstruktor des Ziel-Widgets
    • Indem man sie auf die Festplatte schreibt
    • Navigator erlaubt es nicht, Daten zu übergeben
  3. Was macht Navigator.pop(context, true)?
    • Es öffnet einen neuen Screen namens "true"
    • Es schließt alle Screens des Stapels
    • Es schließt den aktuellen Screen und gibt true an das wartende push zurück