首页 > 解决方案 > 具有灵活高度和可滚动内容的对话框

问题描述

我正在尝试创建一个自定义对话框,该对话框将与其内容一样短,直到该内容太高,此时它应该是可滚动的。

这是我的开始:

showDialog(
  context: context,
  useSafeArea: true,
  barrierDismissible: true,
  useRootNavigator: false,
  builder: (context) => Dialog(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(20),
    ),
    elevation: 3,
    backgroundColor: Theme.of(context).colorScheme.surface,
    child: Padding(
      padding: const EdgeInsets.all(20.0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text(lorem(paragraphs: 1)),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {
              Navigator.pop(context);
            },
            child: Text('OK'),
          ),
        ],
      ),
    ),
  ),
);

这给了我以下结果:

在此处输入图像描述

现在,如果我添加更多文本以使其更高,则对话框的高度会适应:

在此处输入图像描述

如果我们走得更远,在某些时候,我们会进入溢出:

在此处输入图像描述

因此,我将文本包装在 SingleChildScrollView 中,但这不足以修复溢出,因此我将 SingleChildScrollView 包装成 Expanded:

Column(
    mainAxisSize: MainAxisSize.min,
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [
      Expanded(
        child: SingleChildScrollView(
          child: Text(lorem(paragraphs: 30)),
        ),
      ),
      SizedBox(height: 20),
      ElevatedButton(
        onPressed: () {
          Navigator.pop(context);
        },
        child: Text('OK'),
      ),
    ],
)

这次文本按预期滚动,对话框使用了它可以使用的所有垂直空间,但不会更多:

在此处输入图像描述

但是现在如果我再次减小文本大小,因为它比可用空间短,对话框仍然占据所有垂直空间,并在文本和按钮之间留下间隙:

在此处输入图像描述

显然,这不是我想要的。知道如何在不调用 MediaQuery 巫术的情况下完成这项工作吗?

标签: flutterdartdialogflutter-layout

解决方案


您可以使用列和灵活。

void showCustomDialog(BuildContext context, String message) async {
    await showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Container(
            width: double.maxFinite,
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: [                      
                  Text("Description 1",
                      style: TextStyle(fontWeight: FontWeight.bold)),
                  SizedBox(height: 8),
                  Flexible(
                    child: SingleChildScrollView(
                      child: Text(message),
                    ),
                  ),
                  ElevatedButton(
                    onPressed: () {
                       Navigator.of(context).pop();
                    },
                    child: Text("OK"),
                  )
                ]),
          ),
        );
      },
    );
  }

推荐阅读