Flutter中如何实现无Context跳转详解
背景介绍
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return DemoPage();
}));
在日常的项目开发中,我们一般push一个新页面是用上面的方法的,利用Navigator.of(context)
来进行push或者pop操作。
缺点:这种情况是必须传context的,目的是为了利用Navigator.of(context)
来获取到NavigatorState对象,然后才能进行push或者pop操作。
那如果我要实现在项目的任何地方都可以push一个新页面的话,而这个地方有可能获取不到context,所以这个时候,就需要实现无context跳转。
解决方案
无context跳转,本质就是不必要我们每次都去传context参数,然后利用一些操作直接去获取到当前的NavigatorState。
方案1:利用GlobalKey
- 在Flutter中,利用GolbalKey利用获取到对应Widget的State对象。所以,这里,我们可以通过一个GlobalKey的key值,来获取到NavigatorState对象。
- MaterialApp中包装了WidgetsApp,而WidgetsApp包装了Navigator,并且将 Navigator的key属性作为navigatorKey暴露出来了。所以,我们可以通过设置navigatorKey,然后利用这个key去获取到NavigatorState对象。
这里贴一下相关的源码,具体的大家可以自己去看源码。
MaterialApp类:
WidgetsApp类:可以看出,我们定义的navigatorKey,最后是会传给Navigator的key值,所以我们在外面就可以通过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< NavigatorState 对象
static GlobalKey<NavigatorState navigatorKey=GlobalKey();
2、创建MaterialApp的对象的时候,将navigatorKey赋值给MaterialApp。
MaterialApp(
navigatorKey: Router.navigatorKey,
)
使用GlobalKey在任意地方获取NavigatorState对象
navigatorKey.currentState.pushNamed("/login");
方案2:利用NavigatorObserver
- NavigatorObserver,看这名字,就知道是可以用来监听Navigator的变化。比如当push一个新页面的时候,Navigator会监听到NavigatorState发生变化,回调didPush()方法。
注意:NavigatorObserver里面定义了一个NavigatorState对象navigator,所以我们可以通过自定义NavigatorObserver,然后直接利用这个navigator对象来做页面push或者pop操作,这样的话,我们就不用自己去利用context去获取navigatorState对象了。
MaterialApp类,提供了navigatorObservers属性,这样我们就可以自定义NavigatorObserver去监听Navigator的变化。
NavigatorState类,执行instState对象的时候,会将自身赋值到监听的所有observer对象的_navigator里面。
简单的代码实现
1、自定义NavigatorObserver。
class CustomNavigatorObserver extends NavigatorObserver{
static CustomNavigatorObserver _instance;
static CustomNavigatorObserver getInstance() {
if (_instance == null) {
_instance = CustomNavigatorObserver();
}
return _instance;
}
}
2、创建MaterialApp的对象的时候,将CustomNavigatorObserver赋值给MaterialApp
MaterialApp(
navigatorObservers: [CustomNavigatorObserver()],
)
3、使用CustomNavigatorObserver在任意地方进行页面操作
CustomNavigatorObserver.getInstance().navigator.pushNamed("/login");
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对ZaLou.Cn的支持。
- redis AOF保存机制
- 用 TensorFlow 让你的机器人唱首原创给你听
- 不用synchronized块的话如何实现一个原子的i++?
- Oracle升级中的参数补充(r9笔记第2天)
- 【Go 语言,服务器模块】日志系统源码
- wait方法和sleep方法的区别
- Java面试系列10
- python django整理(三)页面基础(仿BBS)
- 高并发场景下的httpClient优化使用
- socket.io 相关:Example: A simple chat server(官方 实例)
- django整理(四)配置setting文件(CSS,JS,images,templates)路径
- idea 远程调试 tomcat web应用
- Java 中冷门的 synthetic 关键字原理解读
- Spring 数据库连接(Connection)绑定线程(Thread)的实现
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法