【问题标题】:Generic navigation listener for whole application整个应用程序的通用导航侦听器
【发布时间】:2020-08-26 08:20:41
【问题描述】:

我正在尝试找到一种方法在我的应用 (MaterialApp) 的 Root 中设置 global 导航侦听器,它可以让我跟踪所有 导航事件,包括实际的路线名称(例如/home/page1)、导航类型

我搜索类似:

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
  }
),

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

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

你有什么线索吗?

提前致谢,

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

【问题讨论】:

  • 你有MaterialApp.navigatorObservers属性
  • @pskink 感谢您的回答,但navigatorObservers 需要在我所有的子页面上设置一个 mixin,我只想设置一次:/
  • 什么混入?你不需要任何mixin,只需在观察者列表中添加一个具体的NavigatorObserver
  • 哦!我的坏是的!这是现在完美的工作!非常感谢!
  • @pskink 我已经编辑了我的问题以帮助其他人,再次感谢您的帮助:)

标签: flutter flutter-dependencies flutter-navigation


【解决方案1】:

最终的解决方案是像这样创建 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!

【讨论】:

  • 实际上是扩展NavigatorObserver,而不是RouteObserver - 它或多或少相同,但...
【解决方案2】:

受@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';
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    相关资源
    最近更新 更多