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