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

Flutter中安卓返回键关闭应用而非返回上页问题求助

问题:Flutter中PopScope组件无法正确拦截安卓返回键,按下后直接关闭应用

我在Flutter代码中添加了PopScope组件,原本期望按下安卓三键导航的返回键时能回到上一页,但实际操作后应用直接关闭了,这不是我想要的效果。

当前代码

1. 添加PopScope的pengajuanScreen代码

@override
Widget build(BuildContext context) {
  return PopScope(
    canPop: true,
    onPopInvoked: (bool didPop) async {
      if (didPop) {
        return;
      }
      Navigator.pop(context); 
    },
    child: Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        leading: Builder(
          builder: (BuildContext context) {
            return IconButton(
              icon: const Icon(Icons.arrow_back),
              color: Colors.black,
              onPressed: () {
                Navigator.pop(context);
              },
            );
          },
        ),
        title: Text(
          'Pengajuan',
          style: TextStyle(color: Colors.black),
        ),
      ),
      // body部分
    ),
  );
}

2. 导航到pengajuanScreen的代码

Navigator.push(
  context,
  MaterialPageRoute(
      builder: (context) => pengajuanScreen(
            id: id,
          )),
);

3. 发起导航的首页代码(已尝试在首页添加PopScope但无效)

@override
Widget build(BuildContext context) {
  double screenWidth = MediaQuery.of(context).size.width;
  double boxWidth = screenWidth - 10;
  String userName = (userData != null && userData!.isNotEmpty)
      ? userData![0]['nama']
      : 'Loading...';
  return Scaffold(
    appBar: // appbar部分
    body: // body部分
    bottomNavigationBar: BottomNavigationBar(
      onTap: (index) {
        if (index == 0) {
          Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => homeScreen(
                      id: id,
                    )),
          );
        } else if (index == 1) {
          Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => marketplaceScreen(
                      id: id,
                    )),
          );
        } else if (index == 2) {
          Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => pengajuanScreen(
                      id: id,
                    )),
          );
        }
      },
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: 'Beranda',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.store),
          label: 'Marketplace',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.attach_money),
          label: 'Pengajuan',
        ),
      ],
      selectedItemColor: Colors.green,
    ),
  );
}

解决方案

问题根源

  1. PopScope配置错误:canPop设为true时,系统会优先执行默认返回行为,直接弹出当前页面甚至关闭应用,你的onPopInvoked逻辑无法有效拦截。
  2. 首页导航逻辑问题:每次点击底部导航都用Navigator.push,导致路由栈不断叠加,回到首页后再按返回键就直接触发应用关闭。

修复步骤

1. 修正pengajuanScreen的PopScope配置

将canPop设为false,完全接管返回逻辑:

@override
Widget build(BuildContext context) {
  return PopScope(
    canPop: false, // 拦截系统默认返回行为
    onPopInvoked: (bool didPop) async {
      if (didPop) {
        return;
      }
      // 手动执行返回操作
      Navigator.pop(context);
    },
    child: Scaffold(
      // 原有Scaffold内容
    ),
  );
}

2. 优化首页底部导航的路由逻辑

避免重复叠加路由,使用pushReplacement替换当前页面:

onTap: (index) {
  // 标记路由名称,避免重复跳转
  final currentRouteName = ModalRoute.of(context)?.settings.name;
  switch(index) {
    case 0:
      if (currentRouteName != '/home') {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            settings: RouteSettings(name: '/home'),
            builder: (context) => homeScreen(id: id),
          ),
        );
      }
      break;
    case 1:
      if (currentRouteName != '/marketplace') {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            settings: RouteSettings(name: '/marketplace'),
            builder: (context) => marketplaceScreen(id: id),
          ),
        );
      }
      break;
    case 2:
      if (currentRouteName != '/pengajuan') {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            settings: RouteSettings(name: '/pengajuan'),
            builder: (context) => pengajuanScreen(id: id),
          ),
        );
      }
      break;
  }
},

3. 首页添加返回拦截(可选)

如果希望首页按返回键时弹出确认框,而非直接关闭应用:

import 'package:flutter/services.dart';

@override
Widget build(BuildContext context) {
  return PopScope(
    canPop: false,
    onPopInvoked: (didPop) async {
      if (didPop) return;
      // 弹出确认退出对话框
      final shouldExit = await showDialog<bool>(
        context: context,
        builder: (context) => AlertDialog(
          title: Text('确认退出'),
          content: Text('确定要关闭应用吗?'),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context, false),
              child: Text('取消'),
            ),
            TextButton(
              onPressed: () => Navigator.pop(context, true),
              child: Text('确定'),
            ),
          ],
        ),
      );
      if (shouldExit == true) {
        SystemNavigator.pop(); // 关闭应用
      }
    },
    child: Scaffold(
      // 原有首页内容
    ),
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:57:13