具有灵活高度和可滚动内容的对话框
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"),
)
]),
),
);
},
);
}
我正在尝试创建一个自定义对话框,该对话框将与其内容一样短,直到该内容太高为止,此时它应该可以滚动。
这是我的开头:
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"),
)
]),
),
);
},
);
}