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