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

Flutter中GoRouter与PopScope配合失效的问题求助

解决GoRouter与PopScope配合时返回拦截失效的问题

问题根源

你的代码里PopScope的用法有误:onPopInvoked回调并不支持返回Future<bool>来控制是否允许返回,且默认情况下canPop为true,系统会直接执行返回行为,导致你的对话框逻辑根本没机会触发。另外,当HomePage作为根路由时,返回操作是退出App,PopScope需要额外处理这个场景。

修正方案

在页面内正确配置PopScope,通过canPop阻止默认返回行为,再在onPopInvoked里手动处理确认逻辑:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: PopScope(
        // 先禁用默认的返回行为
        canPop: false,
        onPopInvoked: (bool didPop) async {
          // didPop为true说明已经完成了pop,直接返回
          if (didPop) return;

          final shouldExit = await showDialog<bool>(
            context: context,
            // 点击对话框外部不关闭,强制用户选择
            barrierDismissible: false,
            builder: (context) => AlertDialog(
              title: const Text('Confirmation'),
              content: const Text('Do you want to exit?'),
              actions: [
                TextButton(
                  onPressed: () => Navigator.of(context).pop(false),
                  child: const Text('No'),
                ),
                TextButton(
                  onPressed: () => Navigator.of(context).pop(true),
                  child: const Text('Yes'),
                ),
              ],
            ),
          );

          if (shouldExit == true) {
            // 判断当前是否是可pop的路由(非根路由)
            if (context.canPop()) {
              context.pop();
            } else {
              // 根路由时退出App
              SystemNavigator.pop();
            }
          }
        },
        child: const Center(child: Text('Home Page Content')),
      ),
    );
  }
}

额外注意事项

  1. 版本兼容性:确保你的Flutter版本在3.14以上,GoRouter版本在10.0以上,这两个版本才对PopScope有完善支持。
  2. 子路由场景:如果HomePage是从其他路由跳转过来的子路由,上述代码同样适用,context.canPop()会自动识别并执行GoRouter的pop操作。
  3. 全局拦截替代方案:如果需要全局控制返回行为,可以在GoRouter配置里使用onPopPage回调,但这种方式更适合全局统一规则,页面级的拦截还是用PopScope更灵活。

内容的提问来源于stack exchange,提问作者Mahammad Azimzada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:36:04