我想根据条件显示警报对话框。不基于用户交互,例如按钮按下事件。
如果在应用状态数据警报对话框中设置了标志,则显示否则,则不显示。
下面是我要显示的示例警报对话框
void _showDialog() {
// flutter defined function
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Alert Dialog title"),
content: new Text("Alert Dialog body"),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
我试图在主屏幕小部件的build方法中调用该方法,但它给了我错误-
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
E/flutter ( 3667): #0 Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:1179:9)
E/flutter ( 3667): #1 Navigator.of (package:flutter/src/widgets/navigator.dart:1186:6)
E/flutter ( 3667): #2 showDialog (package:flutter/src/material/dialog.dart:642:20)
问题是我不知道从哪里调用该_showDialog方法?
答案 0 :(得分:7)
只需覆盖SELECT
Product,
Event_Type,
Quantity
FROM Purchasing
GROUP BY 1,2;
并在initState
内调用您的_showDialog
方法
Timer.run()
答案 1 :(得分:6)
您必须将内容包装在另一个Widget
(最好是无状态)中。
示例:
更改自:
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Trial',
home: Scaffold(
appBar: AppBar(title: Text('List scroll')),
body: Container(
child: Text("Hello world"),
)));
}
}
为此:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Trial',
home: Scaffold(
appBar: AppBar(title: Text('List scroll')), body: new MyHome()));
}
}
class MyHome extends StatelessWidget { // Wrapper Widget
@override
Widget build(BuildContext context) {
Future.delayed(Duration.zero, () => showAlert(context));
return Container(
child: Text("Hello world"),
);
}
void showAlert(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text("hi"),
));
}
}
注意:有关将显示警报包装在Future.delayed(Duration.zero,..)
中的信息,请参见here
答案 2 :(得分:3)
我将其放置在initState
的{{1}}的{{1}}中。
将其放在State
小部件的StatefulWidget
方法中很诱人,但这会多次触发您的警报。
在下面的示例中,当设备未连接到Wifi时,它将显示警报,如果未连接,则显示[重试]按钮。
build
答案 3 :(得分:0)
这就是我以一种简单的方式实现这一目标的方法:
在主屏幕(或任何所需的小部件)的构建方法上:
Future checkFirstRun(BuildContext context) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstRun = prefs.getBool('isFirstRun') ?? true;
if (isFirstRun) {
// Whatever you want to do, E.g. Navigator.push()
prefs.setBool('isFirstRun', false);
} else {
return null;
}
}
然后在小部件的initState上
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => checkFirstRun(context));
}
这可确保在构建窗口小部件后运行该功能。
答案 4 :(得分:0)
如果您使用的是 blocs,请使用 @mirkancal 在此答案中建议的 BlocListener
:Flutter: bloc, how to show an alert dialog
答案 5 :(得分:-1)
我使用Flutter Community开发的软件包解决了它。这里https://pub.dev/packages/after_layout
将此添加到您的pubspec.yaml
after_layout: ^1.0.7+2
并尝试以下示例
import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
class DialogDemo extends StatefulWidget {
@override
_DialogDemoState createState() => _DialogDemoState();
}
class _DialogDemoState extends State<DialogDemo>
with AfterLayoutMixin<DialogDemo> {
@override
void initState() {
super.initState();
}
@override
void afterFirstLayout(BuildContext context) {
_neverSatisfied();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
decoration: BoxDecoration(color: Colors.red),
),
);
}
Future<void> _neverSatisfied() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Rewind and remember'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('You will never be satisfied.'),
Text('You\’re like me. I’m never satisfied.'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Regret'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}