# Navigator Push and Pop — Flutter

Source: https://www.skillbyai.com/en/flutter/n-navigator

> The imperative route stack.

## A stack of routes

The **Navigator** manages a stack of **routes** (full screens or dialogs). `Navigator.push(context, MaterialPageRoute(builder: ...))` puts a new screen on top with a platform-appropriate transition; `Navigator.pop(context, result)` removes it and can return a value to the awaiting caller. `pushReplacement` swaps the current route (useful after sign-in), and `pushAndRemoveUntil` clears the stack. Dialogs and bottom sheets (`showDialog`, `showModalBottomSheet`) are routes too, so they close with `pop`. On Android the system back gesture pops the top route; `PopScope` lets a screen intercept it, for example to confirm discarding unsaved changes.

## Move between screens

Flutter keeps screens on a stack of routes; a router maps URLs and deep links to that stack.

![Three ideas: imperative Navigator, declarative go_router, passing data and deep links.](assets/figures/flutter/section-5-map.svg) — Figure 5.1 — Route stack, router configuration and deep links.

## Push a screen and await a result

Returning data with pop.

```dart
Future<void> pickColour(BuildContext context) async {
  final colour = await Navigator.push<Color>(
    context,
    MaterialPageRoute(builder: (_) => const ColourPickerPage()),
  );
  if (!context.mounted) return; // the widget may be gone after the await
  if (colour != null) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Picked $colour')),
    );
  }
}

// inside ColourPickerPage
ListTile(
  title: const Text('Teal'),
  onTap: () => Navigator.pop(context, Colors.teal),
);
```

## A stack of plates

Each new screen is a plate placed on top; pop lifts the top plate off and you are back to the one underneath, exactly as you left it.

**Quiz:** How does a pushed screen return a value to the screen that opened it?

- [ ] By writing to a global variable only
- [x] By passing it to Navigator.pop, which completes the Future returned by push
- [ ] By calling setState on the parent
- [ ] Screens cannot return values

*Answer:* By passing it to Navigator.pop, which completes the Future returned by push. push returns a Future that completes with the pop result.
