Flutter Route管理

204 阅读1分钟

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;
}