Flutter:更改AlertDialog的宽度

Jul*_*ien 12 dart flutter

我不知道如何更改AlertDialog的默认宽度,我仅成功更改了边框半径:

这是我的代码:

showDialog(
       context: context,
       builder: (_) =>
            new AlertDialog(
               shape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.all(Radius.circular(10.0))
               ),
               content: ProductPreviewScreen(),
            )
    );
Run Code Online (Sandbox Code Playgroud)

预期结果:

在此处输入图片说明 任何的想法?

use*_*821 66

截至 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)
      )
    ],
  )
));
Run Code Online (Sandbox Code Playgroud)

结果是:

对话框示例


Ken*_*ent 54

这比其他答案要简单得多。只需使用构建器来更改正在构建的对话框的大小(用其他语言构建、实例化)。这意味着您还可以查询屏幕尺寸并根据所述屏幕尺寸决定您想要多少空间。例如,平板电脑上的空间比手机上的空间大。如果需要 App bar 等功能,可以让 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,
        );
      },
    ),
  )
);
Run Code Online (Sandbox Code Playgroud)

不同尺寸的示例:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

可选地添加这些以删除不需要的内/外边框空间。

          insetPadding: EdgeInsets.zero,
          contentPadding: EdgeInsets.zero,
          clipBehavior: Clip.antiAliasWithSaveLayer,
Run Code Online (Sandbox Code Playgroud)

  • Shinriyo就是一个例子。不要复制尺寸完全改变以满足您的需要。 (5认同)

Cop*_*oad 25

使用insetPadding属性AlertDialog

AlertDialog(
  title: Text("AlertDialog"),
  insetPadding: EdgeInsets.symmetric(horizontal: 100),
)
Run Code Online (Sandbox Code Playgroud)


Tom*_*m O 10

我认为另一个答案是有问题的,因为:

  1. 动态更新可能会破坏您的应用程序。
  2. 您可能会破坏应用程序中已经存在的对话框。
  3. 通过gitlab / github / etc与其他开发人员共享代码将是有问题的。

这就是我所做的:

步骤1。

复制'dialog.dart'中的代码,并将其粘贴到新文件中,例如:lib> custom_flutter> custom_dialog.dart。

第2步。

这会产生一些导入错误,删除那些导入,然后添加以下行:

import 'package:flutter/material.dart';
Run Code Online (Sandbox Code Playgroud)

第三步

在新文件“ custom_dialog.dart”中找到Dialog类。并替换:

padding: MediaQuery.of(context).viewInsets + const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
Run Code Online (Sandbox Code Playgroud)

有了这个:

padding: MediaQuery.of(context).viewInsets + const EdgeInsets.symmetric(horizontal: 0.0, vertical: 24.0),
Run Code Online (Sandbox Code Playgroud)

第四步。

现在,无论您想在哪里使用此对话框,请添加以下导入语句:

import 'package:my_app_name/custom_flutter/custom_dialog.dart' as customDialog;
Run Code Online (Sandbox Code Playgroud)

步骤五

如果要使用无限制对话框,请使用:

customDialog.AlertDialog() //Unrestricted dialog
Run Code Online (Sandbox Code Playgroud)

如果没有,那就继续使用常规的:

AlertDialog() //Restricted dialog
Run Code Online (Sandbox Code Playgroud)


Yoh*_*ose 9

干预 insetWidth 和未来的构建器等对我来说不起作用 - 只需编辑内容道具的宽度就可以完美工作。

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),
        ),
      );
    });
Run Code Online (Sandbox Code Playgroud)

上述代码的结果


Cir*_*ack 7

我的解决方案是将 Dialog 包含在一个小部件中,该小部件通过修改 MediaQueryData 来消除由 Dialog 类添加的额外填充。

import 'package:myapp/widgets/dialog_inset_defeat.dart';
...

showDialog(
    context: context,
    builder: (_) => DialogInsetDefeat(
      context: context,
      child: SimpleDialog(...),
    )
);
Run Code Online (Sandbox Code Playgroud)

...或使用 showDialogWithInsets() 自定义值:

showDialogWithInsets(
    context: context,
    edgeInsets: EdgeInsets.symmetric(horizontal: 8),
    builder: (_) => SimpleDialog(...),
    )
);
Run Code Online (Sandbox Code Playgroud)

文件 dialog_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>
///  * </sf/ask/3773923471/>
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,
  );
}
Run Code Online (Sandbox Code Playgroud)

从 Flutter 1.8.3 开始对我有用。青年会


小智 7

我终于找到了一种改变 AlertDialog 宽度的方法。只需用 Container 包裹“内容”,并为其设置宽度即可。

return AlertDialog(
...
content: Container(
   width: MediaQuery.of(context).size.width*0.45,
   child: ...
Run Code Online (Sandbox Code Playgroud)

宽度已修改的 AlertDialog


Nao*_*der 7

对我有用的解决方案。

设置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),
);
Run Code Online (Sandbox Code Playgroud)

单独设置 insetPadding 是行不通的。


小智 6

使用 Dialog()

Dialog(
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
  insetPadding: EdgeInsets.all(15),
  child: SingleChildScrollView(
    child: Container(),
    ),
  ),
);
Run Code Online (Sandbox Code Playgroud)


Jer*_*nte 5

您可以按照此处的建议尝试使用ConstrainedBox小部件包装AlertDialog小部件,并为maxWidth参数设置所需的值。

更新

我只是查看了AlertDialog小部件(即Dialog小部件)的父级代码,发现它用minWidth为280像素的ConstrainedBox小部件包装了其子级。这就是为什么我们无法更改AlertDialog小部件的宽度的原因。

幸运的是,我们可以做两件事。第一种选择是更改dialog.dart文件中“对话框”小组件的默认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,

            ...
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样使用AlertDialog:

showDialog(
  context: context,
  builder: (_) => AlertDialog(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(10.0))
      ),
    contentPadding: EdgeInsets.all(0.0),
    content: ProductPreviewScreen(),
    )
  )
);
Run Code Online (Sandbox Code Playgroud)

另一种方法是创建我们自己的自定义对话框。

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,
      )
    )
 );
Run Code Online (Sandbox Code Playgroud)

  • 我认为使用物料警报对话框是不可能的。您可以编写自己的对话框来实现此目的。我认为材料警报对话框已经是insida固定大小的小部件。 (2认同)

Blo*_*oss 5

使用填充小部件

 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,
                )
            ))
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以更改 AlertDialog 属性 insetPadding 这对您来说是一个简单的方法。

 void alertBox() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        insetPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
        // (horizontal:10 = left:10, right:10)(vertical:10 = top:10, bottom:10)
        contentPadding: EdgeInsets.zero,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        content: Container(
          width: MediaQuery.of(context).size.width - 20,
          // width = device width minus insetPadding = deviceWidth - 20  (left:10, right:10 = 20)
          height: MediaQuery.of(context).size.height - 20,
          // height = device height minus insetPadding = deviceHeight - 20  (top:10, bottom:10 = 20)
          child: ClipRRect(
            borderRadius: BorderRadius.circular(10),
            child: Card(
              margin: EdgeInsets.zero,
              color: Colors.amber,
            ),
          ),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)