flutter的无context全局实现路由跳转

3,030 阅读2分钟

背景介绍

开发过程中遇到了一个问题,需要在网络请求拦截器中统一处理登录失效的错误码,给出提示后跳转到登录页面让用户重新去登录,于是开始写Navigator.of(context)???context这里报红的时候就意识到问题不对了,我在网络请求处理类里,根本不知道当前界面是什么,哪来的context。

// 如下路由跳转代码
Navigator.of(context).push(MaterialPageRoute(builder: (context){
  return Login();
}))

问题来了,需要实现context全局化。

解决方案

首先点进了Navigator.of(context)这个方法,发现这个方法返回了一个NavigatorState对象,即Navigator对象的state。

  static NavigatorState of(
    BuildContext context, {
    bool rootNavigator = false,
    bool nullOk = false,
  }) 

要解决无context跳转,本质就是不必要我们每次都去传context参数,然后可用某些操作直接去获取到当前的NavigatorState,一样达到相同目的。

一、利用GlobalKey

  • 在Flutter中,利用GolbalKey利用获取到对应Widget的State对象。所以,这里,我们可以通过一个GlobalKey的key值,来获取到NavigatorState对象。

  • MaterialApp中包装了WidgetsApp,而WidgetsApp包装了Navigator,并且将 Navigator的key属性作为navigatorKey暴露出来了。所以,我们可以通过设置navigatorKey,然后利用这个key去获取到NavigatorState对象。

  • 简单实现

  1. 定义一个GlobalKey< NavigatorState>对象
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
  1. 创建MaterialApp的对象的时候,将navigatorKey赋值给MaterialApp。
MaterialApp(
  navigatorKey: navigatorKey,
);
  1. 使用GlobalKey在任意地方获取NavigatorState对象
navigatorKey.currentState.pushAndRemoveUntil(
              MaterialPageRoute(builder: (context) => Login()),
              (route) => route == null);

二、全局的context

在application中使用getApplicationContext()方法来获取全局的context,那么怎么在Flutter中获取全局context呢? Flutter的中的widget是以Widget树形式存在的,能拿到顶层树的context,不就可以了么。实现: 1、定义 static BuildContext appContext; 2、将主页最外层context赋值给appContext。 3、在需要的地方使用即可。