diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart index 0fb5730f3ce..6e2fb035a99 100644 --- a/packages/flutter/lib/src/material/dropdown_menu.dart +++ b/packages/flutter/lib/src/material/dropdown_menu.dart @@ -884,6 +884,7 @@ class _DropdownMenuState extends State> { currentHighlight = null; controller.close(); } else { + filteredEntries = widget.dropdownMenuEntries; // close to open if (_localTextEditingController!.text.isNotEmpty) { _enableFilter = false; @@ -934,8 +935,6 @@ class _DropdownMenuState extends State> { filteredEntries = widget.filterCallback?.call(filteredEntries, _localTextEditingController!.text) ?? filter(widget.dropdownMenuEntries, _localTextEditingController!); - } else { - filteredEntries = widget.dropdownMenuEntries; } _menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry entry) => entry.enabled); diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart index 6ed4036fcfe..11804862ba5 100644 --- a/packages/flutter/test/material/dropdown_menu_test.dart +++ b/packages/flutter/test/material/dropdown_menu_test.dart @@ -1701,6 +1701,55 @@ void main() { expect(tester.takeException(), isNull); }); + // Regression test for https://github.com/flutter/flutter/issues/165867. + testWidgets('Keyboard navigation only traverses filtered entries', (WidgetTester tester) async { + final TextEditingController controller = TextEditingController(); + addTearDown(controller.dispose); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: DropdownMenu( + requestFocusOnTap: true, + enableFilter: true, + controller: controller, + dropdownMenuEntries: const >[ + DropdownMenuEntry(value: TestMenu.mainMenu0, label: 'Good Match 1'), + DropdownMenuEntry(value: TestMenu.mainMenu1, label: 'Bad Match 1'), + DropdownMenuEntry(value: TestMenu.mainMenu2, label: 'Good Match 2'), + DropdownMenuEntry(value: TestMenu.mainMenu3, label: 'Bad Match 2'), + DropdownMenuEntry(value: TestMenu.mainMenu4, label: 'Good Match 3'), + DropdownMenuEntry(value: TestMenu.mainMenu5, label: 'Bad Match 3'), + ], + ), + ), + ), + ); + + // Open the menu. + await tester.tap(find.byType(DropdownMenu)); + await tester.pump(); + + // Filter the entries to only show the ones with 'Good Match'. + await tester.enterText(find.byType(TextField), 'Good Match'); + await tester.pump(); + + // Since the first entry is already highlighted, navigate to the second item. + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pump(); + expect(controller.text, 'Good Match 2'); + + // Navigate to the third item. + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pump(); + expect(controller.text, 'Good Match 3'); + + // Navigate back to the first item. + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pump(); + expect(controller.text, 'Good Match 1'); + }); + // Regression test for https://github.com/flutter/flutter/issues/147253. testWidgets('Default search prioritises the current highlight', (WidgetTester tester) async { final ThemeData themeData = ThemeData();