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

如何让PopScope的onPopInvoked不响应Navigator.pop()调用?

解决PopScope区分系统返回与手动Navigator.pop的问题

要实现仅系统返回触发onPopInvoked回调、手动调用Navigator.pop()不触发的效果,可以通过状态变量标记手动pop行为,具体实现如下:

代码示例

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  // 标记是否为手动发起的pop
  bool _isManualPop = false;

  // 自定义手动pop方法
  void _manualPop() {
    setState(() {
      _isManualPop = true;
    });
    Navigator.pop(context);
    // 重置标记,避免影响后续系统返回事件
    Future.microtask(() => setState(() => _isManualPop = false));
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvoked: (didPop) {
        // 仅当不是手动pop时,执行系统返回的逻辑
        if (!_isManualPop) {
          log("POP 系统返回触发");
          // 这里可添加自定义逻辑,比如弹窗确认退出
          // 若需要允许系统返回,可手动调用Navigator.pop(context)
        }
      },
      child: Scaffold(
        appBar: AppBar(title: const Text("测试页")),
        body: Center(
          child: ElevatedButton(
            onPressed: _manualPop,
            child: const Text("手动返回"),
          ),
        ),
      ),
    );
  }
}

原理说明

  1. 定义_isManualPop状态变量,标记当前pop是否由代码手动发起。
  2. 封装_manualPop方法,调用Navigator.pop()前将标记设为true,执行后通过Future.microtask重置标记(确保onPopInvoked触发时标记状态正确)。
  3. 在onPopInvoked回调中,仅当_isManualPop为false时,执行系统返回对应的逻辑。

这样既保留了PopScope的特性,又实现了和原WillPopScope一致的行为:仅系统返回按键触发回调,手动调用Navigator.pop()不触发。

内容的提问来源于stack exchange,提问作者Pawan Acharya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:53:12