Flutter AutoRouter报错:上下文需为AutoRouter后代组件的上下文
我清楚问题出在哪,但不知道怎么解决。在main.dart里我创建了带Drawer菜单的Scaffold,Drawer里有跳转到About页面的链接,代码如下:
builder: (BuildContext context, themeProvider, child) { return MaterialApp( home: Scaffold( endDrawer: MenuDrawer(), body: MaterialApp.router( routerConfig: _appRouter.config(), ), ), //end Scaffold ); //end MaterialApp
这段代码会加载初始路由(HOME页面)。
Drawer内部的“About”按钮代码:
OutlinedButton( child: const Text("ABOUT PAGE"), onPressed: () { context.router.pushNamed('/about'); }, ),
点击按钮时触发错误:
══╡ EXCEPTION CAUGHT BY GESTURE
The following assertion was thrown while handling a gesture:
AutoRouter operation requested with a context that does not include an
AutoRouter. The context used to retrieve the Router must be that of a
widget that is a descendant of an AutoRouter widget.
我知道这是因为菜单Drawer在主内容区域之外,不在“home”页面内容里。但我不想给每个页面单独设置菜单(或AppBar和菜单),只想保留一个全局菜单,请问该怎么修改onPressed代码解决问题?
核心问题是MenuDrawer的上下文不是AutoRouter的后代上下文,所以无法找到AutoRouter实例,以下两种方法可以解决:
方法一:通过全局Key获取AutoRouter实例
- 在
main.dart中创建全局的GlobalKey<AutoRouterState>:final GlobalKey<AutoRouterState> _autoRouterKey = GlobalKey<AutoRouterState>(); - 配置
MaterialApp.router时关联这个key:MaterialApp.router( routerConfig: _appRouter.config(routerKey: _autoRouterKey), ), - 修改
MenuDrawer的按钮点击事件,通过全局key调用路由:OutlinedButton( child: const Text("ABOUT PAGE"), onPressed: () { _autoRouterKey.currentState?.pushNamed('/about'); }, ),
注意要把_autoRouterKey通过构造参数传递给MenuDrawer,或者放在全局可访问的位置(比如单独的全局工具类)。
方法二:重构Widget层级(推荐)
调整main.dart的Widget嵌套结构,让Scaffold成为MaterialApp.router的子节点,确保MenuDrawer的上下文是AutoRouter的后代:
builder: (BuildContext context, themeProvider, child) { return MaterialApp.router( routerConfig: _appRouter.config(), builder: (context, child) { return Scaffold( endDrawer: MenuDrawer(), body: child, ); }, ); },
调整后,MenuDrawer的上下文就能正确找到AutoRouter实例,原来的context.router.pushNamed('/about')代码无需修改即可正常工作。
内容的提问来源于stack exchange,提问作者Delmontee

