Navigator.of(context).push(MaterialPageRoute(builder: (context){
return DemoPage();
}));
复制代码
在平常的项目开发中,咱们通常push一个新页面是用上面的方法的,利用Navigator.of(context)来进行push或者pop操做。bash
缺点:这种状况是必须传context的,目的是为了利用Navigator.of(context)来获取到NavigatorState对象,而后才能进行push或者pop操做。ide
那若是我要实如今项目的任何地方均可以push一个新页面的话,而这个地方有可能获取不到context,因此这个时候,就须要实现无context跳转。post
无context跳转,本质就是没必要要咱们每次都去传context参数,而后利用一些操做直接去获取到当前的NavigatorState。ui
这里贴一下相关的源码,具体的你们能够本身去看源码。 MaterialApp类: this
WidgetsApp类:能够看出,咱们定义的navigatorKey,最后是会传给Navigator的key值,因此咱们在外面就能够经过key.currentState()方法来获取到这里的NavigatorState对象了。spa
class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserver {
GlobalKey<NavigatorState> _navigator;
void _updateNavigator() {
_navigator = widget.navigatorKey ?? GlobalObjectKey<NavigatorState>(this);
}
@override
Widget build(BuildContext context) {
Widget navigator;
if (_navigator != null) {
navigator = Navigator(
key: _navigator,
initialRoute: WidgetsBinding.instance.window.defaultRouteName != Navigator.defaultRouteName
? WidgetsBinding.instance.window.defaultRouteName
: widget.initialRoute ?? WidgetsBinding.instance.window.defaultRouteName,
onGenerateRoute: _onGenerateRoute,
onUnknownRoute: _onUnknownRoute,
observers: widget.navigatorObservers,
);
}
}
复制代码
static GlobalKey<NavigatorState> navigatorKey=GlobalKey();
复制代码
MaterialApp(
navigatorKey: Router.navigatorKey,
)
复制代码
navigatorKey.currentState.pushNamed("/login");
复制代码
注意:NavigatorObserver里面定义了一个NavigatorState对象navigator,因此咱们能够经过自定义NavigatorObserver,而后直接利用这个navigator对象来作页面push或者pop操做,这样的话,咱们就不用本身去利用context去获取navigatorState对象了。 3d
class CustomNavigatorObserver extends NavigatorObserver{
static CustomNavigatorObserver _instance;
static CustomNavigatorObserver getInstance() {
if (_instance == null) {
_instance = CustomNavigatorObserver();
}
return _instance;
}
}
复制代码
MaterialApp(
navigatorObservers: [CustomNavigatorObserver()],
)
复制代码
CustomNavigatorObserver.getInstance().navigator.pushNamed("/login");
复制代码
其实这类文章掘金上面也有,本身写这篇文章,主要是本身作下总结。code
大佬们的文章连接:cdn