返回

Flutter 路由源码深入解析:揭秘 Navigator 的奥秘

Android

在 Flutter 的世界里,路由扮演着至关重要的角色,它为应用程序提供流畅、无缝的导航体验。而 Navigator,作为 Flutter 中的路由管理神器,更是开发者不可或缺的利器。今天,我们将深入 Flutter 的源码,一探 Navigator 的奥秘,了解其内部是如何运作的。

Navigator 的 push 方法:开启新的篇章

Navigator.push() 方法是启动新路由的关键。它接收一个 Route 对象作为参数,并将其添加到当前路由堆栈的顶部。Route 对象包含有关新路由的信息,例如其构建器和设置。

在源码中,push() 方法首先会检查当前路由是否已经处于活动的堆栈中。如果是,则会直接调用 pushReplacement() 方法来替换当前路由,而不是添加新的路由。这可以防止重复创建相同的路由。

Future<T?> push<T extends Object?>(Route<T> route) {
  assert(route != null);
  if (_history.last == route)
    return pushReplacement(route, AnimationController.of(_navigator));
  ...
}

接下来,push() 方法会创建一个新的 AnimationController,并将其传递给 route.buildPage() 方法,以便 route 可以使用动画控制器的值来控制其过渡。

final AnimationController animationController = AnimationController(
  duration: Duration(milliseconds: kPushAnimationDuration),
  vsync: this,
);
Page<T> page = route.buildPage(context, animationController);

最后,push() 方法会将新路由添加到路由堆栈中,并触发相应的动画过渡。

_history.add(route);
_didAddRoute(route);

Navigator 的 pop 方法:回退到过去

Navigator.pop() 方法用于从路由堆栈中移除当前路由,返回到上一个路由。

在源码中,pop() 方法首先会检查当前路由是否是根路由。如果是,则会直接调用 popUntil() 方法,将所有路由都移除,直到到达根路由。

Future<T?> pop<T extends Object?>([T? result]) {
  assert(T == dynamic || _history.last != null);
  if (_history.length == 1)
    return popUntil(RoutePredicate((Route<dynamic> route) => false));
  ...
}

如果不是根路由,pop() 方法会创建一个新的 AnimationController,并将其传递给 route.buildPage() 方法,以便 route 可以使用动画控制器的值来控制其过渡。

final AnimationController animationController = AnimationController(
  duration: Duration(milliseconds: kPopAnimationDuration),
  vsync: this,
  reverseDuration: Duration(milliseconds: kPopAnimationDuration),
);
Page<T> page = route.buildPage(context, animationController);

最后,pop() 方法会将当前路由从路由堆栈中移除,并触发相应的动画过渡。

_history.removeLast();
_didRemoveRoute(_history.last);

结语

通过对 Navigator 源码的深入解析,我们揭开了路由管理机制背后的秘密。Navigator.push() 方法负责创建和添加新路由,而 Navigator.pop() 方法负责移除当前路由并返回上一个路由。这些方法的内部实现保证了路由过渡的流畅性和可靠性。

了解 Navigator 的源码可以帮助开发者更好地掌握路由管理,并为应用程序提供卓越的导航体验。通过灵活运用 Navigator,开发者可以创建复杂、用户友好的应用程序,让用户轻松地在不同的屏幕和状态之间穿梭。