在颤动中,我们要在小部件上方覆盖一个对话框。
按下按钮后,我们可以显示对话框。
但是,我们希望在显示喜欢加载对话框的小部件时显示该对话框。
我们实现了如下。
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。看看我的答案是否有类似问题。
building thewidget
dialog