求助:Flutter中基于go_router实现全局退出对话框的方案
使用GoRouter实现Flutter全局退出对话框(无需每个页面单独配置)
直接通过GoRouter的navigatorBuilder钩子就能实现全局的返回拦截,不用给每个页面加onPopScope,具体实现如下:
核心实现代码
final GoRouter router = GoRouter( routes: [ // 你的路由配置示例 GoRoute( path: '/', builder: (context, state) => const HomePage(), ), GoRoute( path: '/detail', builder: (context, state) => const DetailPage(), ), ], // 全局导航器构建钩子,在这里添加全局返回拦截 navigatorBuilder: (context, state, child) { return WillPopScope( onWillPop: () async { // 判断当前路由栈是否只剩根页面 if (state.navigationStack.length == 1) { // 弹出退出确认对话框 final bool? shouldExit = await showDialog<bool>( context: context, barrierDismissible: false, // 点击外部不关闭对话框 builder: (context) => AlertDialog( title: const Text('退出应用'), content: const Text('确定要退出当前应用吗?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('取消'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('退出'), ), ], ), ); // 返回true则允许退出,false则拦截返回 return shouldExit ?? false; } // 非根页面时,正常执行返回操作 return true; }, child: child, ); }, );
关键逻辑说明
- 全局拦截的核心:
navigatorBuilder是GoRouter提供的全局导航树构建入口,我们在这里用WillPopScope包裹整个导航结构,实现全局的返回事件拦截。 - 根页面判断:通过
state.navigationStack.length == 1判断当前路由栈是否只剩根页面,这个方式比判断路径更可靠,适配嵌套路由场景。 - 对话框交互:弹出确认对话框后,根据用户选择返回布尔值:
true允许退出应用,false拦截返回操作,停留在当前页面。
这种方式完全不需要在单个页面中重复配置返回拦截逻辑,一次配置全局生效。
内容的提问来源于stack exchange,提问作者Behzad Ayubifar
相关产品推荐
相关产品推荐

