You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助: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,
    );
  },
);

关键逻辑说明

  1. 全局拦截的核心:navigatorBuilder是GoRouter提供的全局导航树构建入口,我们在这里用WillPopScope包裹整个导航结构,实现全局的返回事件拦截。
  2. 根页面判断:通过state.navigationStack.length == 1判断当前路由栈是否只剩根页面,这个方式比判断路径更可靠,适配嵌套路由场景。
  3. 对话框交互:弹出确认对话框后,根据用户选择返回布尔值:true允许退出应用,false拦截返回操作,停留在当前页面。

这种方式完全不需要在单个页面中重复配置返回拦截逻辑,一次配置全局生效。

内容的提问来源于stack exchange,提问作者Behzad Ayubifar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:27:52