From 7ce8f4abae4bc7e2e480eead1896f99cb03a2c93 Mon Sep 17 00:00:00 2001 From: Yash Johri Date: Wed, 16 Dec 2020 22:53:02 +0530 Subject: [PATCH] Accessibility: repeated label on BottomNavigationBar fixed (#71587) --- .../src/material/bottom_navigation_bar.dart | 1 + .../material/bottom_navigation_bar_test.dart | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/packages/flutter/lib/src/material/bottom_navigation_bar.dart b/packages/flutter/lib/src/material/bottom_navigation_bar.dart index 104e08f75a..bc16eb60e7 100644 --- a/packages/flutter/lib/src/material/bottom_navigation_bar.dart +++ b/packages/flutter/lib/src/material/bottom_navigation_bar.dart @@ -492,6 +492,7 @@ class _BottomNavigationTile extends StatelessWidget { message: item.label!, preferBelow: false, verticalOffset: selectedIconSize + selectedFontSize, + excludeFromSemantics: true, child: result, ); } diff --git a/packages/flutter/test/material/bottom_navigation_bar_test.dart b/packages/flutter/test/material/bottom_navigation_bar_test.dart index 45be2435cd..898fc02147 100644 --- a/packages/flutter/test/material/bottom_navigation_bar_test.dart +++ b/packages/flutter/test/material/bottom_navigation_bar_test.dart @@ -10,6 +10,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:vector_math/vector_math_64.dart' show Vector3; import '../rendering/mock_canvas.dart'; +import '../widgets/semantics_tester.dart'; void main() { testWidgets('BottomNavigationBar callback test', (WidgetTester tester) async { @@ -1786,6 +1787,78 @@ void main() { expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click); }); + + testWidgets('BottomNavigationBar excludes semantics', + (WidgetTester tester) async { + final SemanticsTester semantics = SemanticsTester(tester); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + bottomNavigationBar: BottomNavigationBar( + items: const [ + BottomNavigationBarItem( + label: 'A', + icon: Icon(Icons.ac_unit), + ), + BottomNavigationBarItem( + label: 'B', + icon: Icon(Icons.battery_alert), + ), + ], + ), + ), + ), + ); + + expect( + semantics, + hasSemantics( + TestSemantics.root( + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + children: [ + TestSemantics( + children: [ + TestSemantics( + flags: [SemanticsFlag.scopesRoute], + children: [ + TestSemantics( + children: [ + TestSemantics( + flags: [ + SemanticsFlag.isSelected, + SemanticsFlag.isFocusable + ], + actions: [SemanticsAction.tap], + label: 'A\nTab 1 of 2', + textDirection: TextDirection.ltr, + ), + TestSemantics( + flags: [SemanticsFlag.isFocusable], + actions: [SemanticsAction.tap], + label: 'B\nTab 2 of 2', + textDirection: TextDirection.ltr, + ), + ], + ), + ], + ), + ], + ), + ], + ), + ], + ), + ignoreId: true, + ignoreRect: true, + ignoreTransform: true, + ), + ); + + semantics.dispose(); + }); } Widget boilerplate({ Widget? bottomNavigationBar, required TextDirection textDirection }) {