1、只要有路由变化NavigatorObserver就会执行
/// An interface for observing the behavior of a [Navigator].
class NavigatorObserver {
/// The navigator that the observer is observing, if any.
NavigatorState? get navigator => _navigator;
NavigatorState? _navigator;
/// The [Navigator] pushed `route`.
///
/// The route immediately below that one, and thus the previously active
/// route, is `previousRoute`.
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) { }
/// The [Navigator] popped `route`.
///
/// The route immediately below that one, and thus the newly active
/// route, is `previousRoute`.
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) { }
}
2、响应返回键
// WidgetsBinding
Future<dynamic> _handleNavigationInvocation(MethodCall methodCall) {
switch (methodCall.method) {
case 'popRoute':
return handlePopRoute();
case 'pushRoute':
return handlePushRoute(methodCall.arguments as String);
case 'pushRouteInformation':
return _handlePushRouteInformation(methodCall.arguments as Map<dynamic, dynamic>);
}
return Future<dynamic>.value();
}
可以通过WidgetsBinding.instance.addObserver注册WidgetsBindingObserver信息
// WidgetsBinding
Future<void> handlePopRoute() async {
for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.from(_observers)) {
if (await observer.didPopRoute())
return;
}
SystemNavigator.pop();
}
系统默认存在一个WidgetsBindingObserver,逻辑如下:
@override
Future<bool> didPopRoute() async {
assert(mounted);
// The back button dispatcher should handle the pop route if we use a
// router.
if (_usesRouter)
return false;
final NavigatorState? navigator = _navigator?.currentState;
if (navigator == null)
return false;
return navigator.maybePop();
}
Future<bool> maybePop<T extends Object?>([ T? result ]) async {
final _RouteEntry? lastEntry = _history.cast<_RouteEntry?>().lastWhere(
(_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e),
orElse: () => null,
);
if (lastEntry == null)
return false;
assert(lastEntry.route._navigator == this);
final RoutePopDisposition disposition = await lastEntry.route.willPop(); // this is asynchronous
assert(disposition != null);
if (!mounted)
return true; // forget about this pop, we were disposed in the meantime
final _RouteEntry? newLastEntry = _history.cast<_RouteEntry?>().lastWhere(
(_RouteEntry? e) => e != null && _RouteEntry.isPresentPredicate(e),
orElse: () => null,
);
if (lastEntry != newLastEntry)
return true; // forget about this pop, something happened to our history in the meantime
switch (disposition) {
case RoutePopDisposition.bubble:
return false;
case RoutePopDisposition.pop:
pop(result);
return true;
case RoutePopDisposition.doNotPop:
return true;
}
}
WillPopScope组件会向Route中注册WillPopCallback,存于_willPopCallbacks中
// ModalRoute
@override
Future<RoutePopDisposition> willPop() async {
final _ModalScopeState<T>? scope = _scopeKey.currentState;
assert(scope != null);
for (final WillPopCallback callback in List<WillPopCallback>.from(_willPopCallbacks)) {
if (await callback() != true)
return RoutePopDisposition.doNotPop;
}
return super.willPop();
}
如果没有WillPopCallback信息,则调用父类
// Route
Future<RoutePopDisposition> willPop() async {
return isFirst ? RoutePopDisposition.bubble : RoutePopDisposition.pop;
}