首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Flutter 实战】全局监听路由堆栈变化

【Flutter 实战】全局监听路由堆栈变化

作者头像
老孟Flutter
发布2020-09-22 15:04:35
发布2020-09-22 15:04:35
4.8K00
代码可运行
举报
文章被收录于专栏:FlutterFlutter
运行总次数:0
代码可运行

老孟导读:很多时候我们需要监听路由堆栈的变化,这样可以自定义路由堆栈、方便分析异常日志等。

监听路由堆栈的变化使用 RouteObserver ,首先在 MaterialApp 组件中添加 navigatorObservers

代码语言:javascript
代码运行次数:0
运行
复制
void main() {
  runApp(MyApp());
}

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

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

监听页面设置如下:

代码语言:javascript
代码运行次数:0
运行
复制
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 页面,日志输出如下:

代码语言:javascript
代码运行次数:0
运行
复制
flutter: A-didPush route: /ARouteObserver

进入此页面只调用了 didPush。

从 ARouteObserverDemo 页面跳转到 BRouteObserverDemo 页面(同 ARouteObserverDemo 页面,设置了监听),日志输出如下:

代码语言:javascript
代码运行次数:0
运行
复制
flutter: A-didPushNext route: /ARouteObserver
flutter: B-didPush route: /BRouteObserver

先调用了 ARouteObserverDemo 页面的 didPushNext,然后调用了 BRouteObserverDemo 页面的 didPush。

从 BRouteObserverDemo 页面执行 pop 返回 ARouteObserverDemo 页面,日志输出如下:

代码语言:javascript
代码运行次数:0
运行
复制
flutter: A-didPopNext route: /ARouteObserver
flutter: B-didPop route: /BRouteObserver

先调用了 ARouteObserverDemo 页面的 didPopNext,然后调用了 BRouteObserverDemo 页面的 didPop。

上面的案例仅仅是页面级别的路由堆栈变化,如果想知道整个应用程序路由堆栈变化如何处理?

一种方法是写一个监听路由堆栈的基类,所有页面继承此基类。此方法对源代码的侵入性非常高。

还有一种方法是自定义 RouteObserver,继承RouteObserver并重写其中的方法:

代码语言:javascript
代码运行次数:0
运行
复制
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');
  }
}

使用:

代码语言:javascript
代码运行次数:0
运行
复制
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 页面,日志输出如下:

代码语言:javascript
代码运行次数:0
运行
复制
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)))
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老孟Flutter 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档