如何防止异步函数中的 Navigator.pop() 弹出不再存在的路线?

2023-12-01

在我的 flutter 应用程序中,我有一个按钮,用于启动异步网络操作并在等待其完成时显示一个对话框。完成后,对话框将从导航中弹出,但我遇到了并发问题。这是我的代码:

ElevatedButton(
  onPressed: () async {
    showDialog(
      context: context,
      builder: (context) => Center(child: CircularProgressIndicator()),
    );
    await asyncNetworkOperation();
    Navigator.pop(context);
  },
  child: Text("Press here");
)

如果用户在网络操作正在进行时点击 Android 后退按钮,则会提前弹出该对话框。然后,一旦网络操作完成,就会发出另一个 Navigator.pop(context) ,将导航向后推一个额外的步骤。

如果用户已经弹出对话框,避免执行 Navigator.pop 的最佳方法是什么?我知道我可以阻止后退按钮与WillPopScope小部件,但我希望用户能够在操作时间过长时中止操作。

TLDR:如何预防Navigator.pop()在异步函数中弹出已弹出的路由?


一种通用的方法(可能是推荐的)是使用 Mounted 属性,这需要您使用StatefulWidget:

class MyDialog extends StatefulWidget {
  const MyDialog({Key? key}) : super(key: key);

  @override
  State<MyDialog> createState() => _MyDialogState();
}

class _MyDialogState extends State<MyDialog> {
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('AlertDialog Title'),
      content: const Text('AlertDialog description'),
      actions: <Widget>[
        TextButton(
          onPressed: () async {
            await Future.delayed(const Duration(seconds: 5));
            if (!mounted) {
              return;
            }
            Navigator.pop(context, 'Cancel');
          },
          child: const Text('Cancel'),
        ),
      ],
    );
  }
}

创建后State对象和调用之前initState,框架通过将 State 对象与BuildContext. The State对象保持挂载状态,直到框架调用dispose,之后框架将永远不会询问State对象再次构建,因此您可以检查mounted在安全使用上下文对象之前,除了弹出导航器之外,还可以将其用于其他目的。


See:
  1. https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html
  2. https://api.flutter.dev/flutter/widgets/State/mounted.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何防止异步函数中的 Navigator.pop() 弹出不再存在的路线? 的相关文章

随机推荐