Most of the time, we need to monitor the change of the routing stack, so that we can customize the routing stack, convenient analysis of the exception log, etc.

Observers for route stack changes using RouteObserver, first add navigatorObservers to the MaterialApp component:

void main() {
  runApp(MyApp());
}

RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    returnMaterialApp( ... navigatorObservers: [routeObserver], home: HomePage(), ); }}Copy the code

The listening page Settings are as follows:

class ARouteObserverDemo extends StatefulWidget {
  @override
  _RouteObserverDemoState createState() => _RouteObserverDemoState();
}

class _RouteObserverDemoState extends State<ARouteObserverDemo> with RouteAware {

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    routeObserver.subscribe(this, ModalRoute.of(context));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: RaisedButton(
          child: Text('A RouteObserver'),
          onPressed: () {
            Navigator.of(context).pushNamed('/BRouteObserver'); },),),); }@override
  void dispose() {
    super.dispose();
    routeObserver.unsubscribe(this);
  }

  @override
  void didPush() {
    final route = ModalRoute.of(context).settings.name;
    print('A-didPush route: $route');
  }

  @override
  void didPopNext() {
    final route = ModalRoute.of(context).settings.name;
    print('A-didPopNext route: $route');
  }

  @override
  void didPushNext() {
    final route = ModalRoute.of(context).settings.name;
    print('A-didPushNext route: $route');
  }

  @override
  void didPop() {
    final route = ModalRoute.of(context).settings.name;
    print('A-didPop route: $route'); }}Copy the code

DidPush, didPushNext, didPopNext, and didPop are callbacks to route stack changes.

The ARouteObserverDemo page is displayed. The following output is displayed:

flutter: A-didPush route: /ARouteObserver
Copy the code

Entering this page only calls didPush.

Switch from the ARouteObserverDemo page to the BRouteObserverDemo page (the same as the ARouteObserverDemo page, with listening set). The following output is displayed:

flutter: A-didPushNext route: /ARouteObserver
flutter: B-didPush route: /BRouteObserver
Copy the code

DidPushNext of the ARouteObserverDemo page is called, followed by didPush of the BRouteObserverDemo page.

Run pop from the BRouteObserverDemo page to return to the ARouteObserverDemo page. The following output is displayed:

flutter: A-didPopNext route: /ARouteObserver
flutter: B-didPop route: /BRouteObserver
Copy the code

DidPopNext of the ARouteObserverDemo page is called, followed by didPop of the BRouteObserverDemo page.

The above example is just a page-level routing stack change. What if you want to know about an entire application routing stack change?

One way is to write a base class that listens to the routing stack and all pages inherit from that base class. This approach is very intrusive to the source code.

There is also a custom RouteObserver method that inherits RouteObserver and overwrites its methods:

class MyRouteObserver<R extends Route<dynamic>> extends RouteObserver<R> {
  @override
  void didPush(Route route, Route previousRoute) {
    super.didPush(route, previousRoute);
    print('didPush route: $route,previousRoute:$previousRoute');
  }

  @override
  void didPop(Route route, Route previousRoute) {
    super.didPop(route, previousRoute);
    print('didPop route: $route,previousRoute:$previousRoute');
  }

  @override
  void didReplace({Route newRoute, Route oldRoute}) {
    super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
    print('didReplace newRoute: $newRoute,oldRoute:$oldRoute');
  }

  @override
  void didRemove(Route route, Route previousRoute) {
    super.didRemove(route, previousRoute);
    print('didRemove route: $route,previousRoute:$previousRoute');
  }

  @override
  void didStartUserGesture(Route route, Route previousRoute) {
    super.didStartUserGesture(route, previousRoute);
    print('didStartUserGesture route: $route,previousRoute:$previousRoute');
  }

  @override
  void didStopUserGesture() {
    super.didStopUserGesture();
    print('didStopUserGesture'); }}Copy the code

Use:

void main() {
  runApp(MyApp());
}

MyRouteObserver<PageRoute> myRouteObserver = MyRouteObserver<PageRoute>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      navigatorObservers: [myRouteObserver],
      initialRoute: '/A', home: APage(), ); }}Copy the code

In this case, the system switches from page A to page B. The following output is displayed:

flutter: didPush route: MaterialPageRoute<dynamic>(RouteSettings("/B"A), animation: AnimationController#6D429 (▶0.000; for MaterialPageRoute<dynamic>(/B))),previousRoute:MaterialPageRoute<dynamic>(RouteSettings("/A".null), animation: AnimationController# e60f7 (⏭1.000; paused; for MaterialPageRoute<dynamic>(/A)))

Copy the code

communication

Lao Meng Flutter blog (330 controls usage + practical primer series) : laomengit.com