Welcome back! This is the third article in a series I’ve decided to call: “Flutter 10X, Flutter for Humans” (that’s pronounced “one-oh-x”). Today, we’ll take a look at Flutter 103: Navigating Multiple Screens.

Quick disclaimer: You’re not going to find a lot here that isn’t in the docs, but the big difference is you’ll be able to understand this easier. Don’t get me wrong, Flutter’s documentation has always been fantastic compared to any others! I also think they’ve listened carefully to many things non-Engineers have said over the past two years about docs, and are working very hard to make them as understandable as possible. However, even their great docs are still written by Engineers, for Engineers… but they are working on it.

I, on the other hand, am not an Engineer. I write for humans, and a lot of those aren’t coming to us with iOS or Android backgrounds. Therefore, I word things a bit differently than you might be used to.

So, back to Navigation…

Everything is a Widget; Even if it’s a Page, Screen, Route or Piece of Cheesecake

Screens, Pages, Activities, ViewControllers. Different words, different code to make them, the same result. In Flutter, we get this same result using Navigators and Routes.

When you talk to Flutter people, they still say “page” for the screen you see but technically I suppose we should be calling it a route. The term just never caught on. This is why you see a folder called pages in many Flutter projects, even though it technically should be called “routes”.

So Routes are the Screens/Pages/Activities/ViewControllers, and Navigators are how you get there.

The Straight Shot, Just Get Me There

If you really don’t care about looking pretty and just want to “turn the page”, there are a few ways to do this. Each has its advantages. The MaterialPageRoute is probably the most commonly used method on both iOS and Android.

I know, “Material” PageRoute is commonly used on iOS… ironic, isn’t it? Here’s a basic example, I’ve underlined the parts we care about:

Using a MaterialPageRouteUsing a MaterialPageRoute

Our on Pressed parameter takes an anonymous function, in this case without any parameters of its own (this is why the ( ) is empty). You could also see this written as a lambda (“fat arrow” syntax):

onPressed: () => Navigator.push(context, MaterialPageRoute( ...

Changing pages isn’t exactly a matter of replacing the old one with a new one. It’s more like making a pile of them (it’s called a stack), and every time you change a page you’re pushing a new page onto the stack or pulling one-off and revealing the page under it. This is why the Navigator in the above example is being told to push.

You have to give the Navigator a Context. If you don’t understand Context, a very simplified explanation is, “the situation and status of everything going on in that Widget, and all the ones above it, at the exact moment the function is triggered”. Notice that it doesn’t include the Widgets below that because, at the time this Context is created, those Widgets don’t yet exist. So, there’s no way to know what they are.

So, Context is basically the state of existence at any particular moment. As such, it’s best left to philosophers to figure out, right after they finish contemplating the nature of existence itself.

Now that we know we’re trying to add something to the stack (push) and under what conditions were trying to do it (context), we have to figure out which approach we want to use. That’s where MaterialPageRoute comes in. When you use it, the new page will slide in from the bottom and fade in on Android, and slide and fade in from the right on iOS, unless the user’s language reads right-to-left, in which case the new page will come from the left.

Tip: By default, the old page is kept in memory but you can free up resources if you set maintainState to false.

Now that we know how we’re going to do this, we need to know where we’re going. The builder is the one doing the work and we’re now giving it the context, so it knows the circumstances it has to build under. All that’s left is to tell the builder what to build. Basically, we’re passing the builder an anonymous function that returns our destination Widget’s constructor… hence the ( ) on the end.


Flutter Tutorial: Multiple Screens and How-To Navigate Them
1.05 GEEK