在小部件上显示对话框
问题内容:
在颤动中,我们要在小部件上方覆盖一个对话框。
按下按钮后,我们可以显示对话框。
但是,我们希望在显示喜欢加载对话框的小部件时显示该对话框。
我们实现了如下。
import 'package:flutter/material.dart';
class XxxxxWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// [NG]We want to show dialog on Container widget.
// showMyDialog(context);
return Container(
child: FlatButton(
child: Text('Show'),
onPressed: () {
// [OK]We can show dialog.
showMyDialog(context);
},
),
);
}
void showMyDialog(BuildContext context) {
showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: const Text(
'Message',
),
actions: <Widget>[
FlatButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop(true);
},
),
],
);
},
);
}
}
当我们使用[NG]代码时,会发生以下错误。
I/flutter (28618): When the exception was thrown, this was the stack:
I/flutter (28618): #0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:3436:11)
I/flutter (28618): #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3462:6)
I/flutter (28618): #2 State.setState (package:flutter/src/widgets/framework.dart:1141:14)
I/flutter (28618): #3 OverlayState.insertAll (package:flutter/src/widgets/overlay.dart:301:5)
I/flutter (28618): #4 OverlayRoute.install (package:flutter/src/widgets/routes.dart:40:24)
I/flutter (28618): #5 TransitionRoute.install (package:flutter/src/widgets/routes.dart:182:11)
I/flutter (28618): #6 ModalRoute.install (package:flutter/src/widgets/routes.dart:740:11)
I/flutter (28618): #7 NavigatorState.push (package:flutter/src/widgets/navigator.dart:1443:11)
I/flutter (28618): #8 showDialog (package:flutter/src/material/dialog.dart:642:53)
I/flutter (28618): #9 XxxxxWidget.showMyDialog (package:xxxxx/Widgets/xxxxx_widget.dart:20:5)
I/flutter (28618): #10 XxxxxWidget.build (package:xxxxx/Widgets/xxxxx_widget.dart:7:5)
[abridgement]
我们还尝试了FutureBuilder,但无法解决此问题。
我们应该如何解决这个问题?
$ flutter doctor -v
[✓] Flutter (Channel beta, v0.5.1, on Mac OS X 10.13.6 17G65, locale ja)
• Flutter version 0.5.1 at /Applications/flutter
• Framework revision c7ea3ca377 (3 months ago), 2018-05-29 21:07:33 +0200
• Engine revision 1ed25ca7b7
• Dart version 2.0.0-dev.58.0.flutter-f981f09760
[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
• Android SDK at /Users/xxxxx/src/android-sdks
• Android NDK at /Users/xxxxx/src/android-sdks/ndk-bundle
• Platform android-27, build-tools 27.0.3
• ANDROID_HOME = /Users/xxxxx/src/android-sdks
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)
• All Android licenses accepted.
[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 9.4.1, Build version 9F2000
• ios-deploy 1.9.2
• CocoaPods version 1.5.3
[✓] Android Studio (version 3.1)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 27.1.1
• Dart plugin version 173.4700
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)
[!] VS Code (version 1.25.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected devices (1 available)
• ASUS Z017DA • XXXXXXXXXXXXXXX • android-arm64 • Android 8.0.0 (API 26)
! Doctor found issues in 1 category.
我们已经安装了Flutter扩展程序。但是扑扑医生说没装好。这对于这个问题并不重要。
问题答案:
我们有一次,显示该对话框 完成 以建设小部件。您可以使用如下所示的 Future.delayed 函数(我 测试过 ,它正在工作)。
class XxxxxWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// [NG]We want to show dialog on Container widget.
Future.delayed(Duration.zero, () => showMyDialog(context)); // import 'dart:async';
return Container(
child: FlatButton(.... //same as question
说明:
由于Dart基于 单线程事件循环 ,因此当我们创建异步任务时,它将把这些事件放在事件队列的末尾并继续其当前执行。请参考以下示例以了解更多详细信息,
void main() {
print("first");
Future(() => print("second"));
print("third");
Future(() => print("forth"));
}
输出将是
first
third
second
forth
它非常类似于
DispatchQueue.main.async {
print("Async1") //printJob
}
完成building thewidget
显示后dialog
。看看我的答案是否有类似问题。