Flutter GoRouter:按下返回键关闭ModalBottomSheet的解决方法
解决GoRouter+底部导航栏下ModalBottomSheet返回键不关闭问题
问题原因
你当前用useRootNavigator: true将弹窗挂载在根导航器上,但打开弹窗时传入的是分支导航器(OtherDetailPage所在分支)的context。按下返回键时,GoRouter优先处理分支导航器的路由栈回退,而非根导航器上的弹窗关闭逻辑。
解决方案
方案1:使用根导航器的Context打开弹窗
直接用全局根导航器key获取context来打开弹窗,让弹窗生命周期与根导航器绑定,返回键会优先触发弹窗关闭。
修改弹窗打开代码:
showModalBottomSheet( isScrollControlled: true, useRootNavigator: true, context: rootNavKey.currentContext!, // 替换为根导航器的context enableDrag: false, builder: (context) { return MyModalContent(); }, );
注意:确保
rootNavKey是全局初始化的,且已在GoRouter初始化时传入navigatorKey: rootNavKey。
方案2:用WillPopScope拦截弹窗内的返回事件
在弹窗内容外层包裹WillPopScope,手动拦截返回键事件,关闭弹窗并阻止路由回退。
修改弹窗代码:
showModalBottomSheet( isScrollControlled: true, useRootNavigator: true, context: context, enableDrag: false, builder: (context) { return WillPopScope( onWillPop: () async { Navigator.of(context).pop(); // 关闭弹窗 return false; // 阻止系统默认的路由回退行为 }, child: MyModalContent(), ); }, );
方案3:自定义GoRouter全局返回拦截逻辑
如果需要全局统一处理这类场景,可以在GoRouter初始化时配置onPopPage,优先关闭根导航器上的弹窗再处理路由:
static final router = GoRouter( initialLocation: homePath, navigatorKey: rootNavKey, onPopPage: (route, result) { // 检查根导航器是否有可关闭的弹窗路由 if (rootNavKey.currentState != null && rootNavKey.currentState!.canPop()) { rootNavKey.currentState!.pop(); return false; // 不执行默认的路由回退 } return route.didPop(result); }, routes: [ // 你的路由配置... ], );
内容的提问来源于stack exchange,提问作者giozh
相关产品推荐
相关产品推荐

