overview
Flutter provides a Navigator widget to manage and manipulate the stack while navigating the screens.
During mobile app development we will have some basic navigation cases that need to be handled as shown above, let’s see how Flutter helps to solve those navigation cases.
Small Note
Navigator provides 2 types of functions are
1 2 3 4 | Navigator <span class="token punctuation">.</span> <span class="token function">pushNamed</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> string <span class="token punctuation">)</span> Navigator <span class="token punctuation">.</span> <span class="token function">of</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">pushNamed</span> <span class="token punctuation">(</span> string <span class="token punctuation">)</span> |
The above two calling methods are equivalent and if you read the source then Navigator.pushNamed(context, string)
is a static function calling Navigator.pushNamed(context, string)
1. push, pop
Two of the most basic and most commonly used functions when doing navigation operations
push
Push the widget to the navigator’s stack, each time calling the function is one push widget to the stack
There are 2 types:
push(context, route)
pushNamed(context, string)
push (context, route)
1 2 3 4 5 6 7 8 9 10 11 | Navigator <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> <span class="token function">MaterialPageRoute</span> <span class="token punctuation">(</span> builder <span class="token punctuation">:</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">Screen1</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// or</span> Navigator <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> <span class="token function">MaterialPageRoute</span> <span class="token punctuation">(</span> builder <span class="token punctuation">:</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// do something</span> <span class="token keyword">return</span> <span class="token function">Screen1</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
This gives you greater control over the screen initialization, so you can perform additional preprocessing, or pass parameters to the new screen, etc.
pushNamed (context, string)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">class</span> <span class="token class-name">Routes</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String screen1 <span class="token operator">=</span> <span class="token string">"/screen1"</span> <span class="token punctuation">;</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String screen2 <span class="token operator">=</span> <span class="token string">"/screen2"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">MaterialApp</span> <span class="token punctuation">(</span> routes <span class="token punctuation">:</span> <span class="token punctuation">{</span> Routes <span class="token punctuation">.</span> screen1 <span class="token punctuation">:</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">Screen1</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> Routes <span class="token punctuation">.</span> screen2 <span class="token punctuation">:</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">Screen2</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> Navigator <span class="token punctuation">.</span> <span class="token function">pushNamed</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> Routes <span class="token punctuation">.</span> screen1 <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Above is the definition of all the names in a class Routes, in addition you can define names in the widget locally
1 2 3 4 | <span class="token keyword">class</span> <span class="token class-name">Screen1</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String screen1 <span class="token operator">=</span> <span class="token string">"/screen1"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
This helps you define a short route, but is limited when routeNamed will return a fixed constructor
pop (context)
Perform pop widgets at the top of the stack navigator, each call called a pop until the stack runs out of widgets.
1 2 | Navigator <span class="token punctuation">.</span> <span class="token function">pop</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
2. Transfer data from A push B
From screen A, open screen B and you want to pass some more information, there are two ways to do it:
- Passed through B’s constructor
- Passed through argumments
Passed through the constructor
To do this, in class A you will need to use push(context, route)
.
On the class B side, just calling var is valid
1 2 3 4 5 6 7 8 9 10 11 12 13 | classs B <span class="token punctuation">{</span> <span class="token keyword">final</span> String title <span class="token punctuation">;</span> <span class="token function">B</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token metadata symbol">@require</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> title <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">A</span> <span class="token punctuation">{</span> <span class="token function">toB</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Navigator <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> <span class="token function">MaterialPageRoute</span> <span class="token punctuation">(</span> builder <span class="token punctuation">:</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">B</span> <span class="token punctuation">(</span> <span class="token string">'from A to B'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Passes through arguments
The push functions that support optional param arguments all support data transmission.
You can use push(context, route, arguments)
or pushNamed(context, string, arguments)
to perform propagation from A.
In B to receive, we need to retrieve from arrguments.
1 2 3 4 5 6 7 8 | <span class="token keyword">class</span> <span class="token class-name">A</span> <span class="token punctuation">{</span> <span class="token function">pushNamed</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> <span class="token string">"/B"</span> <span class="token punctuation">,</span> arguments <span class="token punctuation">:</span> <span class="token string">"from A to B"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">B</span> <span class="token punctuation">{</span> String args <span class="token operator">=</span> ModalRoute <span class="token punctuation">.</span> <span class="token function">of</span> <span class="token punctuation">(</span> context <span class="token punctuation">)</span> <span class="token punctuation">.</span> settings <span class="token punctuation">.</span> arguments <span class="token punctuation">}</span> |
Note : since arguments is an object type, when you want to pass many different types of data, you need to create an object wrap all the types you need to pass.
3. return data from B to A
To pass data from B to A, use pop(context, result)
where the result parameter is the data you want to return.
At A, the push function returns the future, so the await push function will receive data from B
1 2 3 4 5 6 7 8 | <span class="token keyword">class</span> <span class="token class-name">B</span> <span class="token punctuation">{</span> Navigator <span class="token punctuation">.</span> <span class="token function">pop</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">A</span> <span class="token punctuation">{</span> <span class="token keyword">final</span> result <span class="token operator">=</span> <span class="token keyword">await</span> Navigator <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> B <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
4. Other push functions
The Navigator also has a few other push functions for those cases that need custom flow navigation as follows:
pushAndRemoveUntuil / pushNamedAndRemoveUntil
pushReplacement / pushReplacementNamed
popAndPushNamed
Above I explained about push/ pushNamed
so below I just talk about the meaning of these functions, not talk about the different ways.
pushAndRemoveUntil / pushNamedAndRemoveUntil (context, route / string, bool)
Implement adding widgets to the stack and pop widgets in the old stack until bool == true
On the UI side, you will see the enter animation of the newly entered push widget.
1 2 3 4 5 6 | Navigator <span class="token punctuation">.</span> <span class="token function">pushAndRemoveUntil</span> <span class="token punctuation">(</span> context <span class="token punctuation">,</span> <span class="token function">MaterialPageRoute</span> <span class="token punctuation">(</span> builder <span class="token punctuation">:</span> <span class="token punctuation">(</span> BuildContext context <span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token function">Screen1</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> ModalRoute <span class="token punctuation">.</span> <span class="token function">withName</span> <span class="token punctuation">(</span> <span class="token string">'/first'</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
If you want to pop all the widgets available on the stack, you can return false at the bool param
Use case:
- After doing the purchase steps, push the status screen and pop all the purchase screens
- After performing the operations and hitting logout, pop all the screens and push login
pushReplacement / pushReplacementNamed
Perform push widget to stack and pop current widget on stack
On the UI side, you will see the enter animation of the newly entered push widget.
Use case:
- From the splash screen open the Home screen
- From the Login screen, login successfully opens the Home screen
popAndPushNamed
Pop the current widget on the stack and push the new widget in. In a sense it is similar to pushReplacement
However, on the UI side, it will see the exit animation of the current widget pop
Use case:
- When looking at the item list, opening the filter, selecting and applying the filter, then pop the filter screen and push the item list screen
5. Other pop functions
Navigator also has some other pop functions for those cases that need custom flow navigation as follows:
- popUntil
- canPop
- maybePop
Let’s go into each category
popUntil (bool)
This function is easy to understand, pop the widget on the stack until bool == true
canPop
return false if this is the first widget in the navigator stack, or stack size = 1. If stack size> 1 then return true.
maybePop = if (canPop) pop
If the stack size is greater than 1, then pop if not
6. Other functions
The following Navigator functions all need the route param (route = MaterialPagedRoute (builder:)). So to do this, you need a reference to the corresponding route that you want to call the function.
Currently, the navigator’s stack cannot be obtained so this will be a bit confusing.
replaceRoute (context, oldRoute, newRoute)
replaceRouteBelow (context, anchorRoute, newRoute)
removeRoute (context, route)
removeRouteBelow (context, anchorRoute)
replaceRoute (context, oldRoute, newRoute)
replace oldROute on the stack with newRoute
replaceRouteBelow (context, anchorRoute, newRoute)
replace the route just below the anchorRoute in the stack with newRoute
removeRoute (context, route)
remove the route in the stack
removeRouteBelow (context, anchorRoute)
remove the route just below the anchorRoute on the stack
Conclusion
This article I have introduced to you about the Navigator widget in Flutter to handle navigation tasks. Depending on the specific requirements when developing, you will choose the most suitable option.