背景说明
做一个小工具时,想执行路由后退,但这需要BuildContext
对象, 于是就近随便找了一个BuildContext
对象,结果flutter出现错误:
FlutterError (Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.)
原因
我们在哪里执行路由pop()
或ScaffoldMessenger相关操作
,就必须用对应widget
的BuildContext
, 有时候还会出现比较绕的情况,比如:你在A组件中定义了个方法,该方法中执行了路由跳转,但该方法你实际是以传参的方式传到了B组件甚至C组件中执行,那此时如果你用A组件的BuildContext那就会报错,实际在哪里执行,就必须用哪个组件的BuildContext对象
解决方案
MaterialApp
的构造函数有个navigatorKey
的参数,定义一个全局的GlobalKey<NavigatorState>
, 再在需要使用当前BuildContext的地方,直接从GlobalKey<NavigatorState>
中获取即可
navigator_util.dart
dart
import 'package:flutter/material.dart';
class NavigatorStateUtil {
// 需要先配置到MaterialApp的navigatorKey属性才可真正使用
static final GlobalKey<NavigatorState> globalNavigatorKey =
GlobalKey<NavigatorState>();
}
使用NavigatorStateUtil
在MaterialApp
初始化时,配置上去

在需要BuildContext
的地方,通过NavigatorStateUtil
获取

参考资料
Flutter中实现无Context跳转 - 掘金 (juejin.cn)
flutter的无context全局实现路由跳转 - 掘金 (juejin.cn)
Flutter 中由 BuildContext 引发的血案 - 知乎 (zhihu.com)
Flutter之基本路由,命名路由跳转,返回上一页,替换路由和返回根路由------Flutter基础系列_flutter go_router 返回_houruoyu3的博客-CSDN博客
Flutter 不利用 BuildContext 跳转页面_flutter中如何实现无context跳转详解-CSDN博客