我遇到了一个问题,从showDialogue()调用Navigator.pop()两次导致屏幕空白.我正在使用Auto_Router包.我该如何解决这个问题?

PopScope widget

 PopScope(
      canPop: false,
      onPopInvoked: (didPop) {
        log('on click back button ${MainApp.router.stack.toList()}');
        log('didPop: $didPop');
        if (didPop) {
          log('after pop ${MainApp.router.stack.toList()}');
          return;
        }
        _showBackDialog();
      },

showbackdialog function

void _showBackDialog() {
    showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          alignment: Alignment.bottomCenter,
          title: const Text('Are you sure?'),
          content: const Text(
            'Are you sure you want to leave this page?',
          ),
          actions: <Widget>[
            TextButton(
              style: TextButton.styleFrom(
                textStyle: Theme.of(context).textTheme.labelLarge,
              ),
              child: const Text('Nevermind'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            TextButton(
              style: TextButton.styleFrom(
                textStyle: Theme.of(context).textTheme.labelLarge,
              ),
              child: const Text('Leave'),
              onPressed: () async {
                Navigator.pop(context);
                Navigator.pop(context);
              },
            ),
          ],
        );
      },
    );
  }

Before Pop before pop

After Pop after pop

即使堆栈路径为空,路径也会继续弹出而不是退出应用程序.

推荐答案

由于在您的情况下,您需要正确退出应用程序,您可以将

按下exit(0),关闭应用程序

因此,对于pop,直到某些屏幕将被使用pop直到,并且要关闭应用程序,您可以这样使用它

onPressed: () async {
     Navigator.pop(context);
     exit(0);
},

或者您可以直接使用

onPressed: () async {
     exit(0);
},

当您多次使用Navigator.pop(context)时,它只是将路由从导航堆栈中弹出,而不一定会关闭整个应用程序.只有在堆栈上没有剩余路由并且按下返回按钮(在Android上)或您显式调用exit(0)时,应用程序才会退出.如果您弹出所有路由,但应用程序仍然停留在空白屏幕上,则可能存在其他问题,例如持续的后台进程或特定于平台的问题

正如您在 comments 中提到的那样

是的,我找到的另一个解决方案是使用SystemNavigator.pop();.然而,两者都实现了我退出应用程序的目标.我不确定哪一个被认为是最佳实践.

您发现,SystemNavigator.pop()对您的情况来说效果很好.好吧,就你的情况而言,我仍然更希望你使用exit(0).why?这是解释

SystemNavigator.pop()exit(0)都服务于不同的目的,以及为什么exit(0)在您的特定用例中"更好"

  • SystemNavigator.pop():此方法专门设计用于模仿系统返回按钮的行为.它会将当前路由从导航堆栈中弹出,类似于在Android上按下返回按钮或在iOS上滑回.它通常用于当您想要在应用程序中导航返回以保持应用程序的预期行为时.

  • exit(0):此方法会立即终止Dart虚拟机进程,有效地关闭整个应用程序.这是退出应用程序的更有力的方法,应谨慎使用.当您想要完全关闭应用程序时,通常使用它,绕过任何导航堆栈或清理过程.

一般来说,对于应用程序内的标准导航,首选SystemNavigator.pop(),而对于需要强制关闭应用程序的情况,例如在某些错误处理场景中或完全退出应用程序时,保留exit(0).

Flutter相关问答推荐

此同步方法会返回True还是False?

如何使用Firebase Firestore来获取外部集合中的文档子集合中的文档

audioQuery不会等待判断存储权限

Flutter 翼doctor 显示的错误,我似乎不能修复.问题:系统32、Android工具链、Windows 10 SDK

如何将Visual Studio代码中Flutter 应用的包名从com.example.XXX更改为Play Store中受限制的包名称

如何使用Dio/Ffltter(前端)和amp;Go(后端)向API发送正确的请求

当键盘在抖动中打开时,如何才能看到包装在SingleChildScrollView中的列中的最后一个小工具?

为什么在setState之后Ffltter Pageview重置为第0页

Flutter - Riverpod 2.0 - 如何访问 onDispose 回调?

自定义类提供程序 Riverpod Flutter 中的可变变量

无法将Null类型的值分配给 const 构造函数中List类型的参数

在 Flutter 中显示有关提供者通知的对话框

在 flutter 的另一个类中使用变量值

Flutter中如何连续获取TextField的文本是否为空?

如何判断 text.contains() 是否包含多个值

函数中的变量在 Dart 中应该有什么关键字?

在 Flutter 中,如何使用文本字段和方形图像进行行布局

在 Flutter 中单击时切换按钮 colored颜色 没有改变

Navigator.push '!_debugLocked' 上的错误:不正确

参数类型MaterialPageRoute不能分配给参数类型String