Flutter: Push, Pop, Push Android-Intent

Building UI in Flutter is pretty simple with all the widgets that the framework provides. But we can’t just have a beautiful application that does nothing functional. We will be required to move around the application or send data back and forth between screens. In Flutter, navigation from one screen to another is possible because of Navigators, a simple widget that maintains a stack of Routes, or in simpler terms, a history of visited screens/pages.

You will find plenty of articles that tell you how to push to a new screen or pop from the current screen, but this article is a little more than that. This would primarily focus on most of the Navigator methods and describe a use-case for each method.

Before we begin…

You mentioned about Routes somewhere, what was that?
Routes is an abstraction for a screen or a page of an app. For example, '/home' will take you to HomeScreen or '/login' will take you to LoginScreen. '/' will be your initial route. This might sound so much similar to Routing in REST API development. So '/' might act like a root.

This is how you would declare your routes in your Flutter application.

new MaterialApp(
  home: new Screen1(),
  routes: <String, WidgetBuilder> {
    '/screen1': (BuildContext context) => new Screen1(),
    '/screen2' : (BuildContext context) => new Screen2(),
    '/screen3' : (BuildContext context) => new Screen3(),
    '/screen4' : (BuildContext context) => new Screen4()
  },
)

Screen1(), Screen2(), etc are the names of the classes for each screen.

Push, push, push.

If you have any knowledge in Data Structures, then you know about Stacks. If you have even basic knowledge of stacks, then you know about push and pop.

If you don’t, pushing is adding element to the top of a stack of elements and popping is removing the top element from the same stack.

So in case of Flutter, when we navigate to another screen, we use the pushmethods and Navigator widget adds the new screen onto the top of the stack. Naturally, the pop methods would remove that screen from the stack.

So lets move to the codebase of our sample project and let’s see how we can move from Screen 1 to Screen 2. You can experiment with the methods by running the sample app.

new RaisedButton(
   onPressed:(){
   Navigator.of(context).pushNamed('/screen2');
},
   child: new Text("Push to Screen 2"),
),

That was short. 

That was indeed. With the help of pushNamed methods, we can navigate to any screen whose route is defined in main.dart. We call them namedRoute for reference. The use-case of this method is pretty straightforward. To simply navigate.

Stack after pushing Screen2

Pop it

Now when we want to get rid of the last visited screen, which is Screen2 in this case, we would need to pop Routes from the Navigator’s stack using the pop methods.

Navigator.of(context).pop();

Remember, this line of code goes inside your onPressed method.

Stack after Screen 2 popped

When using Scaffold, it usually isn’t necessary to explicitly pop the route, because the Scaffold automatically adds a ‘back’ button to its AppBar, which would call Navigator.pop() on pressed. Even in Android, pressing the device back button would do the same. But nevertheless, you might need this method for other usecases such as popping an AlertDialog when user clicks on Cancel button.

Why pop instead of pushing back to the previous screen?


Imagine you have a Hotel Booking app that lists the hotels in your desired location. Clicking on any list item will take you to a screen that has more details about the hotel. You choose one, and you hate the hotel and want to go back to the list. If you push back to the HotelListScreen, you will be keeping your DetailsScreen onto your stack too. So pressing on the back button would take you back to the DetailsScreenSo confusing!

You should try it out instead. Run the sample app, notice the appBar on your Screen1 , it doesn’t have any back button, because it is the initial Route (or home screen), now press Push to Screen 2 and instead of back button, press the Push to Screen1 instead of Pop and now notice the appBar on Screen1. Pressing on the newly appeared back button will take you back to Screen2and you don’t want that in such cases.

This will be the Stack on such a situation

maybePop

Now what if you are on the initial Route and somebody mistakenly tried to pop this screen. Popping the only screen on the stack would close your app, because then it has no route to display. You definitely don’t want your user to have such an unexpected user experience. That’s where maybePop() comes into picture. So it’s like, pop only if you can. Try it out, click on the maybePopButton on Screen1 and it will do nothing. Because there is nothing to pop. Now try the same on Screen3 and it will pop the screen. Because it can.

canPop

It’s amazing that we can do this, but how can I know if this is the initial route? It would be nice if I could display some alert to user in such cases. 
Great question, just call this canPop() method and it would return true if this route can be popped and false if it’s not possible.

Try both these methods canPop and maybePop on Screen1 and Screen3 and see the difference. The print values for canPop will display in your console tab of your IDE.

Find Full tutorial here:
https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31

Leave a Comment