可滾動 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功能的手動測試表明,它們仍然表現出與之前相同的(正確)行為。- 金色測試可能會失敗。
此更改可能導致(先前透過的)金色測試出現差異,因為
SingleChildScrollView現在嵌套了標題和小部件。一些 Flutter 專案已採取措施,透過對 Flutter 除錯構建中使用的語義節點進行金色快照來建立語義測試。
任何反映滾動容器新增的語義金色更新都是預期中的,並且這些差異可以安全地接受。生成的語義樹示例
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