具有灵活高度和可滚动内容的对话框

Dialog with flexible height and scrollable content

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

这是我的开头:

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'),
      ),
    ],
)

这次文本按预期滚动,对话框使用所有垂直 space 它可以但不能更多:

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

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

我建议将 SingleChildScrollView 的位置更改为 Column 的顶部,我希望这样可以正常工作。

类似如下:

              height: 200,
              width: 300,
              child: SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
//Your children's column code 
]

您可以使用 Column 和 Flexible。

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"),
                  )
                ]),
          ),
        );
      },
    );
  }