Starting with Flutter: Screen navigation
Tags: flutter, dart, beginners, tutorial
Published: 2021-03-31 15:06:09

You'll never have only one screen in your app, so, you'll need to navigate across other pages. The question is... how do I do it? Flutter makes it pretty clear with a class simply called **Navigator**.

If you have already some know-how about this class you can check out our tutorial on Routing [here](https://dev.to/theotherdevs/flutter-router-in-4-easy-steps-15if). Otherwise let's dive into `Navigator` world.

### 

### Push & Pop

The two main functions of Navigator are push and pop. Push can be seen as the way to show another screen (Widget), Pop is the way to "remove" current screen and show what was present before.

**Push** needs a Route object which contains all the data needed to to mantain navigation across the app and also identify the animation. So we have MaterialPageRoute and CupertinoPageRoute.

```dart
Navigator.of(context).push(
   MaterialPageRoute(
          builder: (context) => MyWidget()
    )
);
```

Each need to implement the builder which returns your new screen. Also there are other parameters that treat the new page as a fullscreen dialog or other settings.

**Pop** simply removes the top-most route off the navigator and shows the previous view. This is applied not only for "screen" widgets but also dialogs and popups, as there's no "dismiss" method for them

 
### WillPopScope

This Widget can be wrapped around a Scaffold or any top-level tree widget. It has a `onWillPop` interface which is triggered when the widget is going to be popped and, by returning a boolean, you can decide if the pop should happen or not. 

This can be useful to use if you need to do certain tasks as user exits a screen or to show a confirmation dialog before exiting.

```dart
@override
Widget build(BuildContext context) {
  return WillPopScope (
    onWillPop: () async {
      //Do some stuff
      return true; //OR FALSE
    },
    child: Text('WillPop?'),
  );
}
```

### Await on push

Returning data from a screen can be a big requirement, eg. inserting a new car and updating a database when the user clicks "save". In Flutter there's something pretty similar to the "startActivityForResult" of Android, but easier to handle: just **await on push**!

`Navigator.push` is a function which returns a `Future`, completed when the pushed widget is popped. You can send on pop any simple data you wish and obtain it by just awaiting for the result, which will be needed to be casted as it would be a dynamic.

Here's a simple example: Screen A triggers Screen B, which shows a TextField, which written content must be shown by Screen A:

```dart
/**SCREEN A**/
String ourText;

final result = await Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SCREENB()),
  );

  if(result != null)
  setState(){
     ourText = result;
     //THERE WILL BE A Text WIDGET THAT SHOWS IT
  }
}


/**SCREEN B**/
//Show a TextField and attach a textController

ElevatedButton(
  onPressed: () {
    // The Yep button returns "Yep!" as the result.
    Navigator.pop(context, textController.text);
  },
);
```


As you saw navigation is pretty streamlined in Flutter. In order to maintain more order you can create a `Router`, where set all `Navigator` calls. Check our [little guide on creating a simple router](https://dev.to/theotherdevs/flutter-router-in-4-easy-steps-15if) and tell us what you think!