全局监听路由堆栈变化
老孟导读:很多时候我们需要监听路由堆栈的变化,这样可以自定义路由堆栈、方便分析异常日志等。
监听路由堆栈的变化使用 RouteObserver ,首先在 MaterialApp 组件中添加 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(),
);
}
}
监听页面设置如下:
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');
}
}
其中 didPush、didPushNext、didPopNext、didPop 为路由堆栈变化的回调。
从 A 页面跳转到 ARouteObserverDemo 页面,日志输出如下:
flutter: A-didPush route: /ARouteObserver
进入此页面只调用了 didPush。
从 ARouteObserverDemo 页面跳转到 BRouteObserverDemo 页面(同 ARouteObserverDemo 页面,设置了监听),日志输出如下:
flutter: A-didPushNext route: /ARouteObserver
flutter: B-didPush route: /BRouteObserver
先调用了 ARouteObserverDemo 页面的 didPushNext,然后调用了 BRouteObserverDemo 页面的 didPush。
从 BRouteObserverDemo 页面执行 pop 返回 ARouteObserverDemo 页面,日志输出如下:
flutter: A-didPopNext route: /ARouteObserver
flutter: B-didPop route: /BRouteObserver
先调用了 ARouteObserverDemo 页面的 didPopNext,然后调用了 BRouteObserverDemo 页面的 didPop。
上面的案例仅仅是页面级别的路由堆栈变化,如果想知道整个应用程序路由堆栈变化如何处理?
一种方法是写一个监听路由堆栈的基类,所有页面继承此基类。此方法对源代码的侵入性非常高。
还有一种方法是自定义 RouteObserver,继承RouteObserver并重写其中的方法:
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');
}
}
使用:
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(),
);
}
}
此时从 A 页面 跳转到 B 页面,日志输出如下:
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)))
交流
交流
老孟Flutter博客(330个控件用法+实战入门系列文章):http://laomengit.com
欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:
![]() |
![]() |
posted on 2020-09-17 07:16 老孟Flutter 阅读(3936) 评论(1) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现