Flutter开发实现上下文无关跳转
背景介绍
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return DemoPage();
}));
复制代码
在日常项目开发中,我们一般都会使用上面的方法来push新页面,使用Navigator.of(context)来进行push或者pop操作来进行。
缺点:在这种情况下必须传递上下文。目标是使用Navigator.of(context)获取NavigatorState对象,然后执行push或pop操作。
如果我想在项目的某个地方推送一个新页面,这个地方可能没有上下文,所以此时我必须实现上下文无关的跳转。
解决方案
没有上下文跳转,要点是我们不需要每次都传递上下文参数,然后使用一些操作直接获取当前的NavigatorState。
方案一:使用GlobalKey
- 在Flutter中,使用GolbalKey获取Widget对应的State对象。所以这里我们可以通过GlobalKey键值来获取NavigatorState对象。
- MaterialApp 封装了 WidgetsApp,WidgetsApp 封装了 Navigator,并将 Navigator 的 key 属性暴露为 navigatorKey。因此,我们可以设置navigatorKey,然后使用这个key来获取NavigatorState对象。
将相关源码放在这里。您可以自行查看源代码以获取更多信息。 MaterialApp 类:
WidgetsApp 类: 显然,我们定义的 navigatorKey 最终是传递给 Navigator 的键值,所以我们可以通过外面的 key.currentState() 方法获取这里的 NavigatorState 对象。
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,
);
}
}
复制代码
简单的代码实现
- 定义一个GlobalKey对象
static GlobalKey<NavigatorState> navigatorKey=GlobalKey();
复制代码
- 创建MaterialApp对象时,将navigatorKey分配给MaterialApp。
MaterialApp(
navigatorKey: Router.navigatorKey,
)
复制代码
- 使用GlobalKey到处获取NavigatorState对象
navigatorKey.currentState.pushNamed("/login");
复制代码
选项2:使用NavigatorObserver
- NavigatorObserver。如果您查看该名称,您就知道它可以用于跟踪 Navigator 中的更改。例如,当您推送新页面时,Navigator 会监听 NavigatorState 的变化并调用 didPush() 方法。
注:NavigatorObserver 定义了一个 NavigatorState 对象导航器,因此我们可以自定义 NavigatorObserver,然后直接使用这个导航器对象来执行页面推送或弹出操作。在这种情况下,我们不需要使用上下文来获取 navigatorState 对象本身。 。
- MaterialApp 类提供了 navigatorObservers 属性,因此我们可以自定义 NavigatorObserver 来监控 Navigator 的变化。
- NavigatorState类,在执行instState对象时,会将自己分配给所有监控的观察者对象的_navigator。
轻松的代码实现
- 自定义 NavigatorObserver。
class CustomNavigatorObserver extends NavigatorObserver{
static CustomNavigatorObserver _instance;
static CustomNavigatorObserver getInstance() {
if (_instance == null) {
_instance = CustomNavigatorObserver();
}
return _instance;
}
}
复制代码
- 创建MaterialApp对象时,将CustomNavigatorOBServer分配给MaterialApp
MaterialApp(
navigatorObservers: [CustomNavigatorObserver()],
)
复制代码
- 使用CustomNavigatorOBServer可以在任何地方进行分页操作
CustomNavigatorObserver.getInstance().navigator.pushNamed("/login");
复制代码
作者:魔法冬瓜
链接:https://juejin.im/post/5d6b5f31f265da03b76b38 b9
来源:掘金队
版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明出处。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。