我正在学习在 Flutter 中构建应用程序。现在我来警告对话框了。我之前在 Android 和 iOS 中做过,但是如何在 Flutter 中发出警报?
以下是一些相关的 SO 问题:
如何在 Flutter 中设置 AlertDialog Actions 的样式
在颤动的警报对话框中添加下拉菜单
在应用程序主屏幕加载时自动显示警报对话框
如何在颤动中刷新警报对话框
颤动中带有圆角的警报对话框
我想做一个更一般的规范问答,所以我的答案如下。
一键式
showAlertDialog(BuildContext context) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () { },
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("My title"),
content: Text("This is my message."),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
两个按钮
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget continueButton = TextButton(
child: Text("Continue"),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("AlertDialog"),
content: Text("Would you like to continue learning how to use Flutter alerts?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
三个按钮
showAlertDialog(BuildContext context) {
// set up the buttons
Widget remindButton = TextButton(
child: Text("Remind me later"),
onPressed: () {},
);
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget launchButton = TextButton(
child: Text("Launch missile"),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Notice"),
content: Text("Launching this missile will destroy the entire universe. Is this what you intended to do?"),
actions: [
remindButton,
cancelButton,
launchButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
处理按钮按下
上述示例中按钮的 onPressed
回调为空,但您可以添加如下内容:
Widget launchButton = TextButton(
child: Text("Launch missile"),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
launchMissile();
},
);
如果您进行回调 null
,则该按钮将被禁用。
onPressed: null,
https://i.stack.imgur.com/QttPd.png
补充代码
以下是 main.dart
的代码,以防您无法运行上述函数。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter'),
),
body: MyLayout()),
);
}
}
class MyLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
child: Text('Show alert'),
onPressed: () {
showAlertDialog(context);
},
),
);
}
}
// replace this function with the examples above
showAlertDialog(BuildContext context) { ... }
我使用了类似的方法,但我想
将对话框代码作为小部件保存在单独的文件中,以便我可以重复使用它。显示对话框时模糊背景。
https://i.stack.imgur.com/hHwUq.jpg
代码:1. alertDialog_widget.dart
import 'dart:ui';
import 'package:flutter/material.dart';
class BlurryDialog extends StatelessWidget {
String title;
String content;
VoidCallback continueCallBack;
BlurryDialog(this.title, this.content, this.continueCallBack);
TextStyle textStyle = TextStyle (color: Colors.black);
@override
Widget build(BuildContext context) {
return BackdropFilter(
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
child: AlertDialog(
title: new Text(title,style: textStyle,),
content: new Text(content, style: textStyle,),
actions: <Widget>[
new FlatButton(
child: new Text("Continue"),
onPressed: () {
continueCallBack();
},
),
new FlatButton(
child: Text("Cancel"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
));
}
}
您可以通过创建一个新方法来在 main(或任何您想要的地方)中调用它,例如:
_showDialog(BuildContext context)
{
VoidCallback continueCallBack = () => {
Navigator.of(context).pop(),
// code on continue comes here
};
BlurryDialog alert = BlurryDialog("Abort","Are you sure you want to abort this operation?",continueCallBack);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
您可以使用此代码片段来创建两个按钮的警报框,
import 'package:flutter/material.dart';
class BaseAlertDialog extends StatelessWidget {
//When creating please recheck 'context' if there is an error!
Color _color = Color.fromARGB(220, 117, 218 ,255);
String _title;
String _content;
String _yes;
String _no;
Function _yesOnPressed;
Function _noOnPressed;
BaseAlertDialog({String title, String content, Function yesOnPressed, Function noOnPressed, String yes = "Yes", String no = "No"}){
this._title = title;
this._content = content;
this._yesOnPressed = yesOnPressed;
this._noOnPressed = noOnPressed;
this._yes = yes;
this._no = no;
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: new Text(this._title),
content: new Text(this._content),
backgroundColor: this._color,
shape:
RoundedRectangleBorder(borderRadius: new BorderRadius.circular(15)),
actions: <Widget>[
new FlatButton(
child: new Text(this._yes),
textColor: Colors.greenAccent,
onPressed: () {
this._yesOnPressed();
},
),
new FlatButton(
child: Text(this._no),
textColor: Colors.redAccent,
onPressed: () {
this._noOnPressed();
},
),
],
);
}
}
要显示对话框,您可以有一个在导入 BaseAlertDialog
类后调用它的方法 NB
_confirmRegister() {
var baseDialog = BaseAlertDialog(
title: "Confirm Registration",
content: "I Agree that the information provided is correct",
yesOnPressed: () {},
noOnPressed: () {},
yes: "Agree",
no: "Cancel");
showDialog(context: context, builder: (BuildContext context) => baseDialog);
}
输出将是这样的
https://i.stack.imgur.com/v4CzM.png
这是一个较短但完整的代码。
如果您需要一个只有一个按钮的对话框:
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Message'),
content: Text(
'Your file is saved.'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(); // dismisses only the dialog and returns nothing
},
child: new Text('OK'),
),
],
),
);
如果您需要带有是/否按钮的对话框:
onPressed: () async {
bool result = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Confirmation'),
content: Text('Do you want to save?'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(false); // dismisses only the dialog and returns false
},
child: Text('No'),
),
FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(true); // dismisses only the dialog and returns true
},
child: Text('Yes'),
),
],
);
},
);
if (result) {
if (missingvalue) {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text('Missing Value'),
));
} else {
saveObject();
Navigator.of(context).pop(_myObject); // dismisses the entire widget
}
} else {
Navigator.of(context).pop(_myObject); // dismisses the entire widget
}
}
只需使用此自定义对话框类,您不需要将其保留或使其为空,因此您可以轻松进行此自定义。
import 'package:flutter/material.dart';
class CustomAlertDialog extends StatelessWidget {
final Color bgColor;
final String title;
final String message;
final String positiveBtnText;
final String negativeBtnText;
final Function onPostivePressed;
final Function onNegativePressed;
final double circularBorderRadius;
CustomAlertDialog({
this.title,
this.message,
this.circularBorderRadius = 15.0,
this.bgColor = Colors.white,
this.positiveBtnText,
this.negativeBtnText,
this.onPostivePressed,
this.onNegativePressed,
}) : assert(bgColor != null),
assert(circularBorderRadius != null);
@override
Widget build(BuildContext context) {
return AlertDialog(
title: title != null ? Text(title) : null,
content: message != null ? Text(message) : null,
backgroundColor: bgColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(circularBorderRadius)),
actions: <Widget>[
negativeBtnText != null
? FlatButton(
child: Text(negativeBtnText),
textColor: Theme.of(context).accentColor,
onPressed: () {
Navigator.of(context).pop();
if (onNegativePressed != null) {
onNegativePressed();
}
},
)
: null,
positiveBtnText != null
? FlatButton(
child: Text(positiveBtnText),
textColor: Theme.of(context).accentColor,
onPressed: () {
if (onPostivePressed != null) {
onPostivePressed();
}
},
)
: null,
],
);
}
}
用法:
var dialog = CustomAlertDialog(
title: "Logout",
message: "Are you sure, do you want to logout?",
onPostivePressed: () {},
positiveBtnText: 'Yes',
negativeBtnText: 'No');
showDialog(
context: context,
builder: (BuildContext context) => dialog);
输出:
https://i.stack.imgur.com/ONs6z.png
或者您可以为此使用 RFlutter Alert 库。它易于定制且易于使用。它的默认样式包括圆角,您可以根据需要添加按钮。
基本警报:
Alert(context: context, title: "RFLUTTER", desc: "Flutter is awesome.").show();
按钮警报:
Alert(
context: context,
type: AlertType.error,
title: "RFLUTTER ALERT",
desc: "Flutter is more awesome with RFlutter Alert.",
buttons: [
DialogButton(
child: Text(
"COOL",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () => Navigator.pop(context),
width: 120,
)
],
).show();
您还可以定义 generic alert styles。
*我是 RFlutter Alert 的开发者之一。
如果您想要漂亮且响应迅速的警报对话框,那么您可以使用颤振包,例如
rflutter 警报,花式对话框,丰富的警报,甜蜜的警报对话框,简单的对话和简单的警报
这些警报外观漂亮且反应灵敏。其中 rflutter alert 是最好的。目前我正在为我的应用程序使用 rflutter alert。
showAlertDialog(BuildContext context, String message, String heading,
String buttonAcceptTitle, String buttonCancelTitle) {
// set up the buttons
Widget cancelButton = FlatButton(
child: Text(buttonCancelTitle),
onPressed: () {},
);
Widget continueButton = FlatButton(
child: Text(buttonAcceptTitle),
onPressed: () {
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(heading),
content: Text(message),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
称为:
showAlertDialog(context, 'Are you sure you want to delete?', "AppName" , "Ok", "Cancel");
警报对话框的最小代码
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('Title'),
content: Text(
'Content widget',
),
),
);
查看 Flutter Dropdown Banner 可轻松提醒用户注意事件并迅速采取行动,而无需管理呈现、延迟和关闭组件的复杂性。
要设置它:
import 'packages:dropdown_banner/dropdown_banner.dart';
...
class MainApp extends StatelessWidget {
...
@override
Widget build(BuildContext context) {
final navigatorKey = GlobalKey<NavigatorState>();
...
return MaterialApp(
...
home: DropdownBanner(
child: Scaffold(...),
navigatorKey: navigatorKey,
),
);
}
}
要使用它:
import 'packages:dropdown_banner/dropdown_banner.dart';
...
class SomeClass {
...
void doSomethingThenFail() {
DropdownBanner.showBanner(
text: 'Failed to complete network request',
color: Colors.red,
textStyle: TextStyle(color: Colors.white),
);
}
}
这里
显示对话框的另一个简单选项是使用 stacked_services 包
_dialogService.showDialog(
title: "Title",
description: "Dialog message Tex",
);
});
此代码有效并演示了如何获取用户按下的按钮值:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatelessWidget(),
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () => Navigator.pop(context, 'Cancel'),
);
Widget continueButton = TextButton(
child: Text("Ok"),
onPressed: () => Navigator.pop(context, 'Ok'),
);
showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('AlertDialog Title'),
content: const Text('AlertDialog description'),
actions: <Widget>[
cancelButton,
continueButton,
],
),
).then((value) => print(value));
},
child: const Text('Show Dialog'),
);
}
}
https://i.stack.imgur.com/psk0n.jpg
https://i.stack.imgur.com/WAst9l.jpg
Dialog
小部件来实现。它与上面的答案相同,但不使用AlertDialog
,该类可以返回您构建的任何自定义小部件,因此它将显示为弹出窗口。在此medium article中了解更多信息showDialog
是来自package:flutter/src/material/dialog.dart
的方法。我以为我必须进行条件渲染才能显示对话框。