zoukankan      html  css  js  c++  java
  • 全局监听路由堆栈变化

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

    监听路由堆栈的变化使用 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】:

  • 相关阅读:
    学习心得总结(1)
    Git使用总结
    Git管理分支
    Git 常用命令整理
    C#Windows窗体中添加了AxWindowsMediaPlayer的详细用法影响键盘操作的问题
    连接SQLsever数据库在C#中不能操作的问题
    C#中字符串的操作
    iOS TableView如何刷新指定的cell或section
    iOS所有的子视图
    iOStextFiled判断输入长度
  • 原文地址:https://www.cnblogs.com/mengqd/p/13683126.html
Copyright © 2011-2022 走看看