navigation

  • The simple use of a Flutter Dialog
  • Flutter Learning chapter 2 — Drawer and Water pattern compression effects
  • The use and Principles of MobX
  • Flutter learning chapter 4 — Size solution
  • Study of Flutter (5) – Route analysis

preface

In the previous chapter of route analysis, initialization of Navigator, generation of route mapping and observation and subscription have been discussed. This chapter will focus on the form and nature of route.

Analyze the

Let’s go back to the push method of NavigatorState,

Although the method is not long, but a lot of information, briefly, there are the following points:

  • Route
  • _history
  • return route.popped

It simply takes oldRoute from _history, adds route to _history, then calls oldRoute, some life-cycle method of route, and returns Route.poped. One notable feature is the call to route.install(), which we’ll talk about later.

_history

_history is a List that acts as a stack for each route, push, and pop operations that correspond to List add and removeLast, respectively.

Route

Then we see the Route class, paving the way for so long, finally to see the Route itself, the same rules, first take a look at all 👀.

Route

  1. Life cycle type,didPop.didPush, etc.
  2. State type,isCurrent.isFirst.isActiveEtc.
  3. install

The first two categories we will not speak, because know its name and know its meaning 😎. After all, install is the core of the Route, and I don’t know if readers have noticed, but at this point, the connection between Navigator and Route is still vague, and install will reveal the secret between the two. (Don’t ask me how I know so clearly, because I read 🤣 beforehand.)

For the install method, one of the most important classes is OverlayEntity, which provides the information needed for overlays, such as opaque, etc. Overlay, as its name says, is a widget that floats overlays, so a good name is very important. I’m sure you’ve all figured it out. The essence of routing is to include our page in the Overlay widget and Overlay the old page. So it’s easy to understand how to put a popbox in a transparent Overlay and Overlay it on the current page. 🐮! After knowing this relation, the next step is to find out the transformation relation between Route and OverlayEntity. We start from the normally used MaterialPageRoute and dig into its parent class. Finally, we find such a method in ModalRoute.

 @override
  可迭代<OverlayEntry> createOverlayEntries() sync* {
    yield _modalBarrier = OverlayEntry(builder: _buildModalBarrier);
    yield OverlayEntry(builder: _buildModalScope, maintainState: maintainState);
  }
Copy the code

Then we followed up and found the ModalRoute corresponding build method and saw this key:

Widget.route. buildPage doesn’t this clearly tell us that the page was created here, and then we return the MaterialPageRoute, and sure enough

So, to sum up, our routing page is passed to ModalRoute as a widget by buildPage, and then at ModalRoute we wrap the routing page in an Overlay widget by createOverlayEntries. So Install is a process that maps routing pages to Overlay, and Navigator manages routing in and out.

communication

After installing, let’s go back to the question we just asked, there is still one thing left unsolved, that is, the return value route.popped after push. Why on earth do you need such a return value? This is all about communication between routes. When a page exits, it can carry some information back to the previous page. As follows:

So you can see that the pop method result is passed to didPop, so let’s go ahead and do didPop,

Here is another new discovery _popCompleter🙄. What is it? The official description is as follows:

  A way to produce Future objects and to complete them later with a value or error.
Copy the code

It’s a Future object that can be executed later, so it’s strung together. After routing the POP, the completion method of _popCompleter is executed, and the parameters are passed through the Future. The last page just listens for the callback of _popter. This is where the return value for push — route.popped — pops, which, yes, is the Future object for _popter, as follows:

Future<T> get popped => _popCompleter.future;
Copy the code

So, just to clarify, when we push a route, we get the Future object of the next route, and when the next route pops, the Future object performs a callback like this:

  Navigator.of(context).push(MaterialPageRoute(builder:(context) => SettingsPage()).then((value){
                    print(value);
});
Copy the code

In this way, we can listen for the value passed back by the route.

Classification of routing

Opaque routes can be divided into two types:

  • transparent
  • opaque

For a PageRoute route, opaque is true. For a PageRoute route, opaque is true. PopupRoute opaque is false, PopupRoute opaque is false, PopupRoute opaque is false.

conclusion

In fact, this chapter mainly explores the push method to get a glimpse of the essence of routing. In terms of routing, it is still a widget, but hidden in depth. In fact, no matter how complex things are, they are still the most basic and core individuals of a system. This process of analysis is still easy, but the most difficult thing is always from 0 to 1, simple to complex, which requires great wisdom to build, assemble and land.

warehouse

Click flutter_demo to see the full code.

reference

  • Flutter Route resolution