Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 22c8e79

Browse files
authored
Use semantics label for backbutton and closebutton for Android (#110873)
1 parent 2fb5b27 commit 22c8e79

File tree

2 files changed

+91
-11
lines changed

2 files changed

+91
-11
lines changed

packages/flutter/lib/src/material/back_button.dart

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,31 @@ class BackButtonIcon extends StatelessWidget {
2727
/// the current platform (as obtained from the [Theme]).
2828
const BackButtonIcon({ super.key });
2929

30-
/// Returns the appropriate "back" icon for the given `platform`.
31-
static IconData _getIconData(TargetPlatform platform) {
32-
switch (platform) {
30+
@override
31+
Widget build(BuildContext context) {
32+
final String? semanticsLabel;
33+
final IconData data;
34+
switch (Theme.of(context).platform) {
3335
case TargetPlatform.android:
36+
// Android uses semantics label to annotate the back button.
37+
semanticsLabel = MaterialLocalizations.of(context).backButtonTooltip;
38+
data = Icons.arrow_back;
39+
break;
3440
case TargetPlatform.fuchsia:
3541
case TargetPlatform.linux:
3642
case TargetPlatform.windows:
37-
return Icons.arrow_back;
43+
semanticsLabel = null;
44+
data = Icons.arrow_back;
45+
break;
3846
case TargetPlatform.iOS:
3947
case TargetPlatform.macOS:
40-
return Icons.arrow_back_ios;
48+
data = Icons.arrow_back_ios;
49+
semanticsLabel = null;
50+
break;
4151
}
42-
}
4352

44-
@override
45-
Widget build(BuildContext context) => Icon(_getIconData(Theme.of(context).platform));
53+
return Icon(data, semanticLabel: semanticsLabel);
54+
}
4655
}
4756

4857
/// A Material Design back button.
@@ -149,8 +158,22 @@ class CloseButton extends StatelessWidget {
149158
@override
150159
Widget build(BuildContext context) {
151160
assert(debugCheckHasMaterialLocalizations(context));
161+
final String? semanticsLabel;
162+
switch (Theme.of(context).platform) {
163+
case TargetPlatform.android:
164+
// Android uses semantics label to annotate the close button.
165+
semanticsLabel = MaterialLocalizations.of(context).closeButtonTooltip;
166+
break;
167+
case TargetPlatform.fuchsia:
168+
case TargetPlatform.linux:
169+
case TargetPlatform.windows:
170+
case TargetPlatform.iOS:
171+
case TargetPlatform.macOS:
172+
semanticsLabel = null;
173+
break;
174+
}
152175
return IconButton(
153-
icon: const Icon(Icons.close),
176+
icon: Icon(Icons.close, semanticLabel: semanticsLabel),
154177
color: color,
155178
tooltip: MaterialLocalizations.of(context).closeButtonTooltip,
156179
onPressed: () {

packages/flutter/test/material/back_button_test.dart

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'package:flutter/foundation.dart';
56
import 'package:flutter/material.dart';
67
import 'package:flutter_test/flutter_test.dart';
78

@@ -152,17 +153,73 @@ void main() {
152153
tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
153154

154155
await tester.pumpAndSettle();
155-
156+
final String? expectedLabel;
157+
switch(defaultTargetPlatform) {
158+
case TargetPlatform.android:
159+
expectedLabel = 'Back';
160+
break;
161+
case TargetPlatform.fuchsia:
162+
case TargetPlatform.iOS:
163+
case TargetPlatform.linux:
164+
case TargetPlatform.macOS:
165+
case TargetPlatform.windows:
166+
expectedLabel = null;
167+
}
156168
expect(tester.getSemantics(find.byType(BackButton)), matchesSemantics(
157169
tooltip: 'Back',
170+
label: expectedLabel,
158171
isButton: true,
159172
hasEnabledState: true,
160173
isEnabled: true,
161174
hasTapAction: true,
162175
isFocusable: true,
163176
));
164177
handle.dispose();
165-
});
178+
}, variant: TargetPlatformVariant.all());
179+
180+
testWidgets('CloseButton semantics', (WidgetTester tester) async {
181+
final SemanticsHandle handle = tester.ensureSemantics();
182+
await tester.pumpWidget(
183+
MaterialApp(
184+
home: const Material(child: Text('Home')),
185+
routes: <String, WidgetBuilder>{
186+
'/next': (BuildContext context) {
187+
return const Material(
188+
child: Center(
189+
child: CloseButton(),
190+
),
191+
);
192+
},
193+
},
194+
),
195+
);
196+
197+
tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
198+
199+
await tester.pumpAndSettle();
200+
final String? expectedLabel;
201+
switch(defaultTargetPlatform) {
202+
case TargetPlatform.android:
203+
expectedLabel = 'Close';
204+
break;
205+
case TargetPlatform.fuchsia:
206+
case TargetPlatform.iOS:
207+
case TargetPlatform.linux:
208+
case TargetPlatform.macOS:
209+
case TargetPlatform.windows:
210+
expectedLabel = null;
211+
}
212+
expect(tester.getSemantics(find.byType(CloseButton)), matchesSemantics(
213+
tooltip: 'Close',
214+
label: expectedLabel,
215+
isButton: true,
216+
hasEnabledState: true,
217+
isEnabled: true,
218+
hasTapAction: true,
219+
isFocusable: true,
220+
));
221+
handle.dispose();
222+
}, variant: TargetPlatformVariant.all());
166223

167224
testWidgets('CloseButton color', (WidgetTester tester) async {
168225
await tester.pumpWidget(

0 commit comments

Comments
 (0)