整个应用程序的通用导航监听器

Generic navigation listener for whole application

我正在尝试找到一种方法来在我的应用程序 (MaterialApp) 的 Root 中设置 global 导航侦听器,它可以请允许我跟踪所有导航事件,包括实际的路线名称/home/page1 for ex .), 导航类型

我搜索类似:

MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (RouteSettings settings) => route(settings),
  onNavigationChange: (RouteType type, String currentRoute) {
    // type can an enum be like: 'pop', 'push', 'replace' etc.
    // currentRoute is the current route name defined in a pushNamed for example
  }
),

注意:此代码无功能,仅用于说明我想要的内容;)

在我的搜索过程中,我发现了很多像 RouteObserver, route_observer_mixin 这样的解决方案,这几乎是我正在寻找的,但我需要用一个 mixin 来包装我的所有页面......所以没有一个全局解决方案:/

你有什么线索吗?

提前致谢,

编辑感谢@pskink,请参阅下面的解决方案

最终的解决方案是像这样创建 RouteObserver 的扩展:

class MyNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    super.didPush(route, previousRoute);
    if (route is PageRoute) {
      // do stuff
    }
  }

  @override
  void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
    super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
    if (newRoute is PageRoute) {
      // do stuff
    }
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
    super.didPop(route, previousRoute);
    if (previousRoute is PageRoute && route is PageRoute) {
      // do stuff
    }
  }
}

然后在 MaterialApp 小部件上进行设置:

static MyNavigatorObserver observer =
  new MyNavigatorObserver();

MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (RouteSettings settings) => route(settings),
  navigatorObservers: [observer],
),

谢谢@pskink!

受@pskink 的启发,我构建了一个用于日志记录的通用观察器。

设计用于导航 1.0 和 未命名 路线。

import 'package:flutter/material.dart';

class GlobalNavigatorObserver extends RouteObserver<PageRoute> {
  @override
  void didPush(route, previousRoute) {
    super.didPush(route, previousRoute);
    _log('push', previousRoute, route);
  }

  @override
  void didPop(route, previousRoute) {
    super.didPop(route, previousRoute);
    _log('pop', route, previousRoute);
  }

  void _log(String method, Route? fromRoute, Route? toRoute) {
    debugPrint('[Navigator] ${_getPageName(fromRoute)} => ${_getPageName(toRoute)} ($method)');
  }

  /// Try to get page name from route.
  String _getPageName(dynamic route) {
    // Because the builder field is not on a common class, we must try dynamically.
    try {
      final routeBuilderString = route.builder.toString();   // Example: 'Closure: (BuildContext) => WashingsPage'
      return routeBuilderString.substring(routeBuilderString.lastIndexOf(' ') + 1);
    } catch(_) {
      return 'X';
    }
  }
}