Lao Meng's guide : Many times we need to monitor changes in the routing stack, so that we can customize the routing stack and analyze exception logs.
Use RouteObserver to monitor changes in the routing stack . First add in the MaterialApp component navigatorObservers
:
void main() {
runApp(MyApp());
}
RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
...
navigatorObservers: [routeObserver],
home: HomePage(),
);
}
}
The monitoring 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');
}
}
Among them, didPush, didPushNext, didPopNext, didPop are callbacks for routing stack changes.
Jump from page A to page ARouteObserverDemo, the log output is as follows:
flutter: A-didPush route: /ARouteObserver
Entering this page only called didPush.
Jump from the ARouteObserverDemo page to the BRouteObserverDemo page (same as the ARouteObserverDemo page, with monitoring set), the log output is as follows:
flutter: A-didPushNext route: /ARouteObserver
flutter: B-didPush route: /BRouteObserver
First called didPushNext on the ARouteObserverDemo page, and then called didPush on the BRouteObserverDemo page.
Execute pop from the BRouteObserverDemo page to return to the ARouteObserverDemo page, the log output is as follows:
flutter: A-didPopNext route: /ARouteObserver
flutter: B-didPop route: /BRouteObserver
First call didPopNext on the ARouteObserverDemo page, and then call didPop on the BRouteObserverDemo page.
The above case is just a page-level routing stack change, if you want to know how to deal with the entire application routing stack change?
One way is to write a base class that monitors the routing stack, and all pages inherit this base class. This method is very invasive to the source code.
Another method is to customize RouteObserver, inherit RouteObserver and rewrite the method:
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');
}
}
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(),
);
}
}
At this time, jump from page A to page B, and the log output is as follows:
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)))
communicate with
communicate with
Laomeng Flutter blog (330 control usage + actual combat introduction series): http://laomengit.com
Welcome to join the Flutter exchange group (WeChat: laomengit) and follow the public account [Lao Meng Flutter]: