Navigation basics
Navigation in Flutter is a stack model: the Navigator pushes screens on top of each other, and pop removes the topmost one.
Navigator.push(context, MaterialPageRoute(builder: ...))adds a screenNavigator.pop(context)goes back, and its second argument returns a valuepushReplacementreplaces the current screen (login → home, say)pushAndRemoveUntilclears the stack and opens a new screen (on sign-out)
push returns a `Future`, which is easy to miss: it completes with whatever the screen passes to pop.
There are two ways to pass data between screens:
- Constructor —
MaterialPageRoute(builder: (_) => DetailScreen(id: order.id)). Type-safe, and it should be your first choice - Named route with arguments —
Navigator.pushNamed(context, '/detail', arguments: id). It gives you a central route table, butargumentsisObject?and needs a cast
That missing type safety is a genuine problem — which is exactly why packages like go_router offer typed parameters.
Interview tip. The Future returned by push comes up often: "how do you get a result back from a picker screen?" The answer: final result = await Navigator.push<Item>(...), with Navigator.pop(context, selectedItem) on the second screen. The result can be null when the user backs out — mentioning that completes the answer.
📚 Sources and documentation
- Navigation and routingofficialdocs.flutter.dev
- Navigator classofficialapi.flutter.dev
`push`, `pop`, `pushReplacement` and returning results are documented with examples.
- App architecture guideofficialdocs.flutter.dev