整个应用程序的通用导航监听器
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';
}
}
}
我正在尝试找到一种方法来在我的应用程序 (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';
}
}
}