可滚动AlertDialog(不再弃用)
摘要
#AlertDialog
现在在内容溢出时会自动滚动。
上下文
#在此更改之前,当AlertDialog
小部件的内容过高时,显示会溢出,导致内容被剪裁。这导致了以下问题
- 无法查看被剪裁的内容部分。
- 大多数对话框在内容下方都有按钮提示用户执行操作。如果内容溢出,遮挡了按钮,用户可能不知道它们的存在。
变更描述
#以前的方法将标题和内容小部件依次列在一个Column
小部件中。
dart
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (title != null)
Padding(
padding: titlePadding ?? EdgeInsets.fromLTRB(24, 24, 24, content == null ? 20 : 0),
child: DefaultTextStyle(
style: titleTextStyle ?? dialogTheme.titleTextStyle ?? theme.textTheme.title,
child: Semantics(
child: title,
namesRoute: true,
container: true,
),
),
),
if (content != null)
Flexible(
child: Padding(
padding: contentPadding,
child: DefaultTextStyle(
style: contentTextStyle ?? dialogTheme.contentTextStyle ?? theme.textTheme.subhead,
child: content,
),
),
),
// ...
],
);
新方法将这两个小部件包装在一个按钮栏上方的SingleChildScrollView
中,使这两个小部件成为同一可滚动的一部分,并在对话框底部显示按钮栏。
dart
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (title != null || content != null)
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (title != null)
titleWidget,
if (content != null)
contentWidget,
],
),
),
// ...
],
),
迁移指南
#此更改可能会导致以下问题
- 由于添加了
SingleChildScrollView
,语义测试可能会失败。 对
Talkback
和VoiceOver
功能的手动测试表明,它们仍然表现出与之前相同的(正确)行为。- Golden测试可能会失败。
此更改可能导致(先前通过的)golden测试出现差异,因为
SingleChildScrollView
现在嵌套了标题和小部件内容。一些Flutter项目通过获取Flutter调试版本中使用的语义节点的golden来创建语义测试。
反映滚动容器添加的任何语义golden更新都是预期的,这些差异应该可以安全地接受。示例生成的语义树
flutter: ├─SemanticsNode#30 <-- SingleChildScrollView
flutter: │ flags: hasImplicitScrolling
flutter: │ scrollExtentMin: 0.0
flutter: │ scrollPosition: 0.0
flutter: │ scrollExtentMax: 0.0
flutter: │
flutter: ├─SemanticsNode#31 <-- title
flutter: │ flags: namesRoute
flutter: │ label: "Hello"
flutter: │
flutter: └─SemanticsNode#32 <-- contents
flutter: label: "Huge content"
- 布局更改可能会由于滚动视图而导致。
如果对话框之前已经溢出,则此更改会纠正此问题。此布局更改是预期的。
如果保留在代码中,AlertDialog.content
中的嵌套SingleChildScrollView
应该可以正常工作,但如果不需要,则应将其删除,因为它可能会造成混淆。
迁移前的代码
dart
AlertDialog(
title: Text(
'Very, very large title that is also scrollable',
textScaleFactor: 5,
),
content: SingleChildScrollView( // won't be scrollable
child: Text('Scrollable content', textScaleFactor: 5),
),
actions: <Widget>[
TextButton(child: Text('Button 1'), onPressed: () {}),
TextButton(child: Text('Button 2'), onPressed: () {}),
],
)
迁移后的代码
dart
AlertDialog(
title: Text('Very, very large title', textScaleFactor: 5),
content: Text('Very, very large content', textScaleFactor: 5),
actions: <Widget>[
TextButton(child: Text('Button 1'), onPressed: () {}),
TextButton(child: Text('Button 2'), onPressed: () {}),
],
)
时间线
#包含在版本中:1.16.3
稳定版发布:1.17
参考
#设计文档
API文档
相关问题
相关PR
除非另有说明,否则本网站上的文档反映了Flutter的最新稳定版本。页面上次更新于 2024-04-04。 查看源代码 或 报告问题.