Flutter中showDialog()后关闭Dialog
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter中showDialog()后关闭Dialog相关的知识,希望对你有一定的参考价值。
参考技术A 在耗时操作的时候,一般都要弹出一个加载框,然后在完成的时候再把加载框关掉,在Flutter中可以直接用showDialog()来弹出一个对话框。这是一个简单的提示对话框,包含了关闭按钮,点击就能关闭。但一般的耗时操作完成,就需要我们自己把dialog关闭掉。
首先,开启dialog的时机。由于我们需要获取到BuildContext,所以就得等build()方法走完,这里可以用Future.delayed()来等创建好BuildContext再进行创建,或者用Timer来延迟操作,我选择了前者。
其中delayed()在initState()结尾来做就行,这里参考网友封装了一个LoadingDialog。
那么接下来要在什么时机关闭呢?
一开始,我理所当然的以为,是在异步方法结束后,去更新界面的时候关闭,也就是setState(() )的时候,可是不管怎么尝试,用Navigator.pop()不行,用Navigator.of(context, rootNavigator: true).pop(result)也不行,用FlutterBoost.singleton.close(id)也不行,用FlutterBoost.singleton.closeCurrent()也不行,都会直接把非Dialog的页面也关闭掉,这让我百思不得其解,因为showDialog()的本质也是新建了一个Route出来,也就是最顶层的页面是弹出的Dialog,可是为什么关不掉呢。
一番思前想后,把showDialog的逻辑移到和异步逻辑同级,也就是setState(() )外面,然后把showDialog()自身创建的BuildContext传进去就能正常关闭了。也就是,在setState(() )的时候,其实用的context还是非Dialog页面的,所以关闭的当然就不是Dialog了。
持有Dialog自己的BuildContext,然后在异步以后调用就行了。
在 Flutter 中使用 showDialog() 后清除 Getx 参数
【中文标题】在 Flutter 中使用 showDialog() 后清除 Getx 参数【英文标题】:Getx argumentsbeing cleared after using showDialog() in Flutter 【发布时间】:2021-05-29 14:03:37 【问题描述】:在 showDialog 方法执行后,使用的 Getx 参数被清除。
_someMethod (BuildContext context) async
print(Get.arguments['myVariable'].toString()); // Value is available at this stage
await showDialog(
context: context,
builder: (context) => new AlertDialog(
//Simple logic to select between two buttons
); // get some Confirmation to execute some logic
print(Get.arguments['myVariable'].toString()); // Variable is lost and an error is thrown
我还想知道如何使用 Getx 来显示小吃吧,而不会丢失上面的参数。
【问题讨论】:
【参考方案1】:执行此操作的一种方法是将数据复制到控制器内的变量中并从中使用,而不是直接从Get.arguments
中使用它,因此当小部件树重建时,状态会被保留。
例子
class MyController extends GetxController
final myArgument = ''.obs;
@override
void onInit()
myArgument(Get.arguments['myVariable'] as String);
super.onInit();
class MyView extends GetView<MyController>
@override
Widget build(BuildContext context)
return Scaffold(
body: Expanded(
child: Center(child: Obx(() => Text(controller.myArgument()))),
),
);
更新
由于您正在寻找没有页面转换的解决方案,另一种实现方式是在 Controller 中创建一个功能或直接从 UI 分配。就这样……
class MyController extends GetxController
final myArgument = 'empty'.obs;
class MyView extends GetView<MyController>
@override
Widget build(BuildContext context)
return Scaffold(
body: Expanded(
child: ElevatedButton(
onPressed: () => _someMethod(context),
child: Obx(() => Text(controller.myArgument())),
),
),
);
void _someMethod(BuildContext context) async
// store it in the state.
controller.myArgument(Get.arguments['myVariable'] as String);
await showDialog(
context: context,
builder: (context) => new AlertDialog(...),
);
print(controller.myArgument()); // This should work
更新 2(如果您不使用 GetView)
class MyController extends GetxController
final myArgument = 'empty'.obs;
class MyView extends StatelessWidget
final controller = Get.put(MyController());
@override
Widget build(BuildContext context)
return Scaffold(
body: Expanded(
child: ElevatedButton(
onPressed: () => _someMethod(context),
child: Obx(() => Text(controller.myArgument())),
),
),
);
void _someMethod(BuildContext context) async
// store it in the state.
controller.myArgument(Get.arguments['myVariable'] as String);
await showDialog(
context: context,
builder: (context) => new AlertDialog(...),
);
print(controller.myArgument()); // This should work
更新 3(不推荐)
如果您真的真的很想不惜一切代价避免使用控制器,您可以将它分配给StatefulWidget
中的普通变量,尽管我不推荐这种方法,因为它被认为是不好的实践并违反框架本身的目标,并可能在未来让您的团队感到困惑。
class MyPage extends StatefulWidget
const MyPage( Key? key ) : super(key: key);
@override
_MyPageState createState() => _MyPageState();
class _MyPageState extends State<MyPage>
String _myArgument = 'empty';
@override
Widget build(BuildContext context)
return Scaffold(
body: Expanded(
child: ElevatedButton(
onPressed: () => _someMethod(context),
child: Text(_myArgument),
),
),
);
void _someMethod(BuildContext context) async
// store it in the state.
setState(()
_myArgument = Get.arguments['myVariable'] as String;
);
await showDialog(
context: context,
builder: (context) => new AlertDialog(...),
);
print(_myArgument); // This should work
【讨论】:
抱歉格式错误,我是用手机写的,回家后会尽快更新 感谢您的建议,但我正在寻找一种无需页面转换即可更新 Getx 参数的解决方案。 我更新了我的答案,请看看@CharithJayasanka以上是关于Flutter中showDialog()后关闭Dialog的主要内容,如果未能解决你的问题,请参考以下文章
SaveFileDialog 在调用 showDialog() 后直接自动关闭
showdialog()的窗体点击message的按钮后,窗体也关闭了?
使用 showdialog 和 textfield 在 Flutter 中更新单个 Listview 项目
WPF程序 当关闭一个窗体后,重新打开报错 关闭窗口之后无法设置 Visibility 或者调用 Show或ShowDialog
在showDialog中Flutter Navigator.of(context).pop(),在ios中关闭整个应用程序