截至2020年5月,如果您想更改对话框的插页填充,则只需使用Dialog类并覆盖'insetPadding'属性即可。如果需要,您可以使对话框延伸到屏幕边缘。
您还可以通过使对话框表面本身透明,然后添加任何组件来创建一些很酷的自定义对话框。例如:
showDialog(Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(10),
child: Stack(
overflow: Overflow.visible,
alignment: Alignment.center,
children: <Widget>[
Container(
width: double.infinity,
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.lightBlue
),
padding: EdgeInsets.fromLTRB(20, 50, 20, 20),
child: Text("You can make cool stuff!",
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center
),
),
Positioned(
top: -100,
child: Image.network("https://i.imgur.com/2yaf2wb.png", width: 150, height: 150)
)
],
)
));
结果如下:
这比其他答案描述的要简单得多。只需使用构建器在构建(在其他语言中称为实例化)对话框时更改其大小即可。这意味着您还可以查询屏幕大小并根据所述屏幕大小决定需要多少空间。例如,在平板电脑上需要更多的空间,而在手机上则需要较少的空间。如果您需要应用程序栏和其他功能,则可以将Scaffold设置为Container的子项。
showDialog(
context: context,
builder: (_) => new AlertDialog(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(10.0))),
content: Builder(
builder: (context) {
// Get available height and width of the build area of this widget. Make a choice depending on the size.
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
return Container(
height: height - 400,
width: width - 400,
);
},
),
)
);
不同尺寸的示例:
如有需要,可以添加以下内容以去除不必要的内/外边框空间。
insetPadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
clipBehavior: Clip.antiAliasWithSaveLayer,
为增加宽度:
AlertDialog(
title: Text("AlertDialog"),
insetPadding: EdgeInsets.zero,
)
减小宽度:
AlertDialog(
title: Text("AlertDialog"),
insetPadding: EdgeInsets.symmetric(horizontal: 100),
)
调用此方法:
showGeneralDialog(
context: context,
barrierColor: Colors.black.withOpacity(0.5),
pageBuilder: (_, __, ___) {
return Material(
color: Colors.transparent,
child: Center(
child: Container(
color: Colors.white, // Dialog background
width: 120, // Dialog width
height: 50, // Dialog height
child: SingleChildScrollView(
child: Column(
children: [
Text('I am a small Dialog'),
],
),
),
),
),
);
},
);
Container
或SizedBox
内使用对话框。 - Samuel Nde你可以尝试像这里建议的那样,用ConstrainedBox小部件包装你的AlertDialog小部件,并为maxWidth参数设置所需的值。
更新
我刚刚查看了AlertDialog小部件的父级Dialog小部件的代码,并发现它使用minWidth为280像素的ConstrainedBox小部件包装其子级。这就是为什么我们无法更改AlertDialog小部件宽度的原因。
幸运的是,我们有两个选择。第一种选择是修改dialog.dart文件中Dialog小部件的默认minWidth。请注意,更改此设置将影响所有使用Dialog小部件的flutter项目。
//inside dialog.dart
class Dialog extends StatelessWidget {
...
@override
Widget build(BuildContext context) {
final DialogTheme dialogTheme = DialogTheme.of(context);
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets + const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
duration: insetAnimationDuration,
curve: insetAnimationCurve,
child: MediaQuery.removeViewInsets(
removeLeft: true,
removeTop: true,
removeRight: true,
removeBottom: true,
context: context,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: 280.0), // You can set your desired value for minWidth here
child: Material(
elevation: 24.0,
...
您可以像这样使用AlertDialog:
showDialog(
context: context,
builder: (_) => AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))
),
contentPadding: EdgeInsets.all(0.0),
content: ProductPreviewScreen(),
)
)
);
另一种方法是创建我们自己的定制对话框。
创建我们自己的定制对话框是另外一种方式。
showDialog(
context: context,
builder: (_) => Center( // Aligns the container to center
child: Container( // A simplified version of dialog.
width: 100.0,
height: 56.0,
color: Colors.pink,
)
)
);
尝试调整insetWidth和future builder等方法对我无效 - 只需编辑content属性的宽度即可完美解决。
showDialog(
context: context,
builder: (context) {
Future.delayed(Duration(seconds: 1000), () {
Navigator.of(context).pop(true);
});
return AlertDialog(
insetPadding: EdgeInsets.all(8.0),
title: Text(
"Time to go pro!",
textAlign: TextAlign.center,
),
content: Container(
width: MediaQuery.of(context).size.width,
child: BuySheet(
applePayEnabled: applePayEnabled,
googlePayEnabled: googlePayEnabled,
applePayMerchantId: applePayMerchantId,
squareLocationId: squareLocationId),
),
);
});
insetPadding + 容器的宽度
可以创建全宽对话框。 - Jerry Padding(
padding: EdgeInsets.only(left: 50.0, right: 50.0),
child://AlertDialog or any other Dialog you can use
Dialog(
elevation: 0.0,
backgroundColor: Colors.transparent,
child: Container(
width: 10.0,
height: 50.0,
color: Colors.red,
)
))
Padding(padding: "..",child:
- BIS Tech对我有效的解决方案。
设置AlertDialog的insetPadding。
此外,将内容包装在SizedBox中,并将宽度设置为MediaQuery.of(context).size.width。
return AlertDialog(
content: SizedBox(
width: MediaQuery.of(context).size.width,
child: const Text("Content"),
),
insetPadding: const EdgeInsets.all(10),
);
仅设置insetPadding是无效的。
AlertDialog
比其默认宽度小的情况,但它不能使其大于其默认大小,这正是OP所要求的。 - Regular Joreturn AlertDialog(
...
content: Container(
width: MediaQuery.of(context).size.width*0.45,
child: ...
使用 Dialog()
Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
insetPadding: EdgeInsets.all(15),
child: SingleChildScrollView(
child: Container(),
),
),
);
import 'package:myapp/widgets/dialog_inset_defeat.dart';
...
showDialog(
context: context,
builder: (_) => DialogInsetDefeat(
context: context,
child: SimpleDialog(...),
)
);
...或使用showDialogWithInsets()来自定义值:
showDialogWithInsets(
context: context,
edgeInsets: EdgeInsets.symmetric(horizontal: 8),
builder: (_) => SimpleDialog(...),
)
);
文件对话框_inset_defeat.dart
import 'package:flutter/material.dart';
/// A widget to defeat the hard coded insets of the [Dialog] class which
/// are [EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0)].
///
/// See also:
///
/// * [Dialog], for dialogs that have a message and some buttons.
/// * [showDialog], which actually displays the dialog and returns its result.
/// * <https://material.io/design/components/dialogs.html>
/// * <https://dev59.com/fFQJ5IYBdhLWcg3wbFIW
class DialogInsetDefeat extends StatelessWidget {
final BuildContext context;
final Widget child;
final deInset = EdgeInsets.symmetric(horizontal: -40, vertical: -24);
final EdgeInsets edgeInsets;
DialogInsetDefeat({@required this.context, @required this.child, this.edgeInsets});
@override
Widget build(BuildContext context) {
var netEdgeInsets = deInset + (edgeInsets ?? EdgeInsets.zero);
return MediaQuery(
data: MediaQuery.of(context).copyWith(viewInsets: netEdgeInsets),
child: child,
);
}
}
/// Displays a Material dialog using the above DialogInsetDefeat class.
/// Meant to be a drop-in replacement for showDialog().
///
/// See also:
///
/// * [Dialog], on which [SimpleDialog] and [AlertDialog] are based.
/// * [showDialog], which allows for customization of the dialog popup.
/// * <https://material.io/design/components/dialogs.html>
Future<T> showDialogWithInsets<T>({
@required BuildContext context,
bool barrierDismissible = true,
@required WidgetBuilder builder,
EdgeInsets edgeInsets,
}) {
return showDialog(
context: context,
builder: (_) => DialogInsetDefeat(
context: context,
edgeInsets: edgeInsets,
child: Builder(builder: builder),
),
// Edited! barrierDismissible: barrierDismissible = true,
barrierDismissible: barrierDismissible,
);
}
从Flutter 1.8.3版本开始,对我来说可行。但你的情况可能不同。
insetPadding
确实适用于AlertDialog
以及Dialog
,但是Dialog
没有使用ConstrainedBox
实现,而AlertDialog
则有。这意味着AlertDialog
的大小基于其子元素自适应。为了克服这个问题并使AlertDialog
响应insetPadding
,请将AlertDialog
的content
设置为Center(child: SizedBox(width: MediaQuery.of(context).size.width, child: {YOUR ACTUAL ALERT CONTENT}))
。您还可以摆脱Center
并将SizeBox.height
设置为与宽度相同。参见:https://github.com/flutter/flutter/issues/61154#issuecomment-770627805 - ubiquibacon