Unverified Commit fd0554ba authored by chunhtai's avatar chunhtai Committed by GitHub

always adds alert label for alert dialog in Android (#65973)

parent cb92ffc7
...@@ -413,9 +413,11 @@ class AlertDialog extends StatelessWidget { ...@@ -413,9 +413,11 @@ class AlertDialog extends StatelessWidget {
/// The semantic label of the dialog used by accessibility frameworks to /// The semantic label of the dialog used by accessibility frameworks to
/// announce screen transitions when the dialog is opened and closed. /// announce screen transitions when the dialog is opened and closed.
/// ///
/// If this label is not provided, a semantic label will be inferred from the /// In iOS, if this label is not provided, a semantic label will be inferred
/// [title] if it is not null. If there is no title, the label will be taken /// from the [title] if it is not null.
/// from [MaterialLocalizations.alertDialogLabel]. ///
/// In Android, if this label is not provided, the dialog will use the
/// [MaterialLocalizations.alertDialogLabel] as its label.
/// ///
/// See also: /// See also:
/// ///
...@@ -455,18 +457,15 @@ class AlertDialog extends StatelessWidget { ...@@ -455,18 +457,15 @@ class AlertDialog extends StatelessWidget {
final DialogTheme dialogTheme = DialogTheme.of(context); final DialogTheme dialogTheme = DialogTheme.of(context);
String label = semanticLabel; String label = semanticLabel;
if (title == null) {
switch (theme.platform) { switch (theme.platform) {
case TargetPlatform.iOS: case TargetPlatform.iOS:
case TargetPlatform.macOS: case TargetPlatform.macOS:
label = semanticLabel;
break; break;
case TargetPlatform.android: case TargetPlatform.android:
case TargetPlatform.fuchsia: case TargetPlatform.fuchsia:
case TargetPlatform.linux: case TargetPlatform.linux:
case TargetPlatform.windows: case TargetPlatform.windows:
label = semanticLabel ?? MaterialLocalizations.of(context)?.alertDialogLabel; label ??= MaterialLocalizations.of(context)?.alertDialogLabel;
}
} }
// The paddingScaleFactor is used to adjust the padding of Dialog's // The paddingScaleFactor is used to adjust the padding of Dialog's
...@@ -491,7 +490,7 @@ class AlertDialog extends StatelessWidget { ...@@ -491,7 +490,7 @@ class AlertDialog extends StatelessWidget {
style: titleTextStyle ?? dialogTheme.titleTextStyle ?? theme.textTheme.headline6, style: titleTextStyle ?? dialogTheme.titleTextStyle ?? theme.textTheme.headline6,
child: Semantics( child: Semantics(
child: title, child: title,
namesRoute: true, namesRoute: label == null,
container: true, container: true,
), ),
), ),
...@@ -569,6 +568,8 @@ class AlertDialog extends StatelessWidget { ...@@ -569,6 +568,8 @@ class AlertDialog extends StatelessWidget {
if (label != null) if (label != null)
dialogChild = Semantics( dialogChild = Semantics(
scopesRoute: true,
explicitChildNodes: true,
namesRoute: true, namesRoute: true,
label: label, label: label,
child: dialogChild, child: dialogChild,
......
...@@ -1275,10 +1275,12 @@ void main() { ...@@ -1275,10 +1275,12 @@ void main() {
)); ));
}); });
testWidgets('Dialog widget contains route semantics from title', (WidgetTester tester) async { testWidgets('AlertDialog widget contains route semantics from title for iOS', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Material( home: Material(
child: Builder( child: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -1321,6 +1323,62 @@ void main() { ...@@ -1321,6 +1323,62 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('AlertDialog widget always contains alert route semantics for android', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.android),
home: Material(
child: Builder(
builder: (BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('X'),
onPressed: () {
showDialog<void>(
context: context,
builder: (BuildContext context) {
return const AlertDialog(
title: Text('Title'),
content: Text('Y'),
actions: <Widget>[],
);
},
);
},
),
);
},
),
),
),
);
expect(semantics, isNot(includesNodeWith(
label: 'Title',
flags: <SemanticsFlag>[SemanticsFlag.namesRoute],
)));
expect(semantics, isNot(includesNodeWith(
label: 'Alert',
flags: <SemanticsFlag>[SemanticsFlag.namesRoute, SemanticsFlag.scopesRoute],
)));
await tester.tap(find.text('X'));
await tester.pumpAndSettle();
// It does not use 'Title' as route semantics
expect(semantics, isNot(includesNodeWith(
label: 'Title',
flags: <SemanticsFlag>[SemanticsFlag.namesRoute],
)));
expect(semantics, includesNodeWith(
label: 'Alert',
flags: <SemanticsFlag>[SemanticsFlag.namesRoute, SemanticsFlag.scopesRoute],
));
semantics.dispose();
});
testWidgets('Dismissible.confirmDismiss defers to an AlertDialog', (WidgetTester tester) async { testWidgets('Dismissible.confirmDismiss defers to an AlertDialog', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final List<int> dismissedItems = <int>[]; final List<int> dismissedItems = <int>[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment