Code前端首页关于Code前端联系我们

Flutter开发实现上下文无关跳转

terry 2年前 (2023-09-23) 阅读数 81 #移动小程序

背景介绍

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 类: Flutter开发实现无Context跳转

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,
      );
    }
}
复制代码

简单的代码实现

  1. 定义一个GlobalKey对象
  static GlobalKey<NavigatorState> navigatorKey=GlobalKey();
复制代码
  1. 创建MaterialApp对象时,将navigatorKey分配给MaterialApp。
MaterialApp(
          navigatorKey: Router.navigatorKey,
)
复制代码
  1. 使用GlobalKey到处获取NavigatorState对象
navigatorKey.currentState.pushNamed("/login");
复制代码

选项2:使用NavigatorObserver

  • NavigatorObserver。如果您查看该名称,您就知道它可以用于跟踪 Navigator 中的更改。例如,当您推送新页面时,Navigator 会监听 NavigatorState 的变化并调用 didPush() 方法。

注:NavigatorObserver 定义了一个 NavigatorState 对象导航器,因此我们可以自定义 NavigatorObserver,然后直接使用这个导航器对象来执行页面推送或弹出操作。在这种情况下,我们不需要使用上下文来获取 navigatorState 对象本身。 。 Flutter开发实现无Context跳转

  • MaterialApp 类提供了 navigatorObservers 属性,因此我们可以自定义 NavigatorObserver 来监控 Navigator 的变化。
    Flutter开发实现无Context跳转
  • NavigatorState类,在执行instState对象时,会将自己分配给所有监控的观察者对象的_navigator。
    Flutter开发实现无Context跳转

轻松的代码实现

  1. 自定义 NavigatorObserver。
class CustomNavigatorObserver extends NavigatorObserver{
  static CustomNavigatorObserver _instance;

  static CustomNavigatorObserver getInstance() {
    if (_instance == null) {
      _instance = CustomNavigatorObserver();
    }
    return _instance;
  }
}
复制代码
  1. 创建MaterialApp对象时,将CustomNavigatorOBServer分配给MaterialApp
MaterialApp(
          navigatorObservers: [CustomNavigatorObserver()],
)
复制代码
  1. 使用CustomNavigatorOBServer可以在任何地方进行分页操作
CustomNavigatorObserver.getInstance().navigator.pushNamed("/login");
复制代码

作者:魔法冬瓜
链接:https://juejin.im/post/5d6b5f31f265da03b76b38 b9
来源:掘金队
版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明出处。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门