Navigation made easy with Flutter
Tags: flutter, beginners, dart, tutorial
Published: 2021-08-06 18:48:11

Flutter is a framework for the dart programming language used for building cross-platform mobile apps and even web pages. Flutter converts code into the native language (Kotlin/Java, Swift for apps and HTML, CSS JS for web). 

Although, which app or website is better without navigation amongst screens or pages respectively unless you have single-page applications. 

Let's understand how Flutter provides such ease in navigation.

## Concept:

* Flutter implements the concept of **Stack** datatype in making navigation possible.
* In normal terms, Stack is a pile of objects referring to the concept of LIFO(Last In First Out). For example, the stack of books, the stack of money, etc. 
* In Flutter's case, there is a stack of screens. Scaffolds or any custom widget which represents a screen.


> Note: Stack widget and stack referred here are two different cases. 
Here, a stack is referred to as datatype not [Stack] (https://api.flutter.dev/flutter/widgets/Stack-class.html).


## Methods of navigating:

### Push()

![Push](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b6ansdtvbn6oh9u3sfq8.png)

* In the above code snippet, **Navigator** class provides method **push** which does the same function as in datatype. It pushes the screen on the top of the screen which is currently been rendered.
* Navigator accepts context to locate the position of the current Scaffold(Screen) in the widget tree.
* Then after, We pass another so-called method in push(). Moreover, **MaterialPageRoute** is not mandatory. You can also provide **CupertinoPageRoute** which will differ in transition effect only.
* To check out more about them: [CupertinoPageRoute](https://api.flutter.dev/flutter/cupertino/CupertinoPageRoute-class.html)
[MaterialPageRoute](https://api.flutter.dev/flutter/material/MaterialPageRoute-class.html)
* It accepts builder argument to build the screen to which you will navigate.
* The following screen can be provided by arrow function or normal function as shown in snippet.

### PushNamed()

![PushNamed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6oc6qrcic7nqhh85ovb.png)

* It has the same functionality as **push()** do but rather than navigating dynamically, it accepts routes provided and accordingly proceeds.
* Similarly, it starts with ```Navigator.of(context)```, and then we implement **pushNamed** method. It accepts the route name as its argument which will tell Flutter where to navigate.
> Important points to note:
* It is good to set a static route name so that it can be used not only in that particular file but also in the file where you set functions of navigation according to these route names.
* For example:
![Routes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xtxre0vj8l9t5jgkoyyh.png)
* In the above snippet, routes argument is passed which is available in **MaterialApp** which is the entry widget of your app. It consists of all the routes available or mentioned in your widgets.

* To add the route we need to provide the route name by the way mentioned in the snippet. The class enum in which your route is and calling it like it's property ```For e.g, Alignment.center```

* Then we provide value to route name in the form of arrow function of context, and the screen or rather the class constructor which should be rendered after navigation.

* Other than route name, we can also see the arguments parameter. It is simply the arguments you want to pass to the page we will be going to. For e.g, there is a shopping app and you want to navigate to the details of a product by clicking on it then you can pass the id of it and it will render all the details of the product of id passed as an argument.

* To accept the argument, the following method can be used:
![ModalRoute](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdlyw6tqv84ezis811la.png)
Note that you need to provide the data type in which your arguments will be passed on. Then you can simply access it by ``` routeArgs['id'] ```

### Pop()
![Pop](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tms0ix3b9z10xzgbgcma.png)
* From above snippet, it clearly tells that pop process is simple.
However, we can see that an Id argument is passed in it. What is it?
* It is the parameter that is passed back reverse to the page it goes to. 
* For e.g, if SecondPage pops and Flutter renders FirstPage back then the Id argument will be passed to FirstPage and we can perform various methods with it.
![then](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0y5tjxixtkg92ixa3hb2.png)
* Where we pushed the page we came from, we can add then method following push and receive the data.

### Other push/pop methods:

* pushReplacement() / pushNamedReplacement: It is also an important. What Flutter did till now was keep adding screens on top of each other every time we navigate. It would lead to memory leaks in the future. The above method just replaces the screen with a new one.

* pushAndRemoveUntil() / pushNamedAndRemoveUntil(): It will push the page and remove all other routes as soon as the condition provided it met.

* popAndPushNamed(): It will dispose of the current page and push another page according to the route provided.

* popUntil(): It will repeatedly pop pages until the condition is met.

* canPop(): It will check if the page can be popped. For e.g, if there isn't any page to go back to.

* restorablePopAndPushNamed(): It will pop the current route of the navigator and push a named route in its place.

* maybePop(): It checks for the willPop() method and return result accordingly. Head here to find out more => [maybePop](https://api.flutter.dev/flutter/widgets/Navigator/maybePop.html).

Thus, there can be many ways to navigate between pages and optimization.