8000 Fix `DropdownMenu` entry selection with enableFilter · flutter/flutter@010db58 · GitHub
[go: up one dir, main page]

Skip to content

Commit 010db58

Browse files
committed
Fix DropdownMenu entry selection with enableFilter
1 parent be75408 commit 010db58

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,9 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
912912
text: entry.label,
913913
selection: TextSelection.collapsed(offset: entry.label.length),
914914
);
915-
_selectedEntryIndex = i;
915+
_selectedEntryIndex = widget.dropdownMenuEntries.indexWhere(
916+
(DropdownMenuEntry<T> entry) => entry.value == filteredEntries[i].value,
917+
);
916918
currentHighlight = widget.enableSearch ? i : null;
917919
widget.onSelected?.call(entry.value);
918920
_enableFilter = false;
@@ -1005,7 +1007,9 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
10051007
text: entry.label,
10061008
selection: TextSelection.collapsed(offset: entry.label.length),
10071009
);
1008-
_selectedEntryIndex = currentHighlight;
1010+
_selectedEntryIndex = widget.dropdownMenuEntries.indexWhere(
1011+
(DropdownMenuEntry<T> entry) => entry.value == filteredEntries[currentHighlight!].value,
1012+
);
10091013
widget.onSelected?.call(entry.value);
10101014
}
10111015
} else {

packages/flutter/test/material/dropdown_menu_test.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,6 +2599,64 @@ void main() {
25992599
},
26002600
);
26012601

2602+
testWidgets('Entry selection in filtered entries should persist after the filter is cleared', (
2603+
WidgetTester tester,
2604+
) async {
2605+
final TextEditingController controller = TextEditingController();
2606+
addTearDown(controller.dispose);
2607+
2608+
await tester.pumpWidget(
2609+
MaterialApp(
2610+
home: StatefulBuilder(
2611+
builder: (BuildContext context, StateSetter setState) {
2612+
String getFirstItemLabel() => 'A1';
2613+
2614+
return Scaffold(
2615+
body: Column(
2616+
children: <Widget>[
2617+
DropdownMenu<TestMenu>(
2618+
requestFocusOnTap: true,
2619+
enableFilter: true,
2620+
controller: controller,
2621+
dropdownMenuEntries: <DropdownMenuEntry<TestMenu>>[
2622+
DropdownMenuEntry<TestMenu>(
2623+
value: TestMenu.mainMenu0,
2624+
// The use of a function is necessary to make the list mutable,
2625+
// since immutable lists' selection does not rematch.
2626+
label: getFirstItemLabel(),
2627+
),
2628+
const DropdownMenuEntry<TestMenu>(value: TestMenu.mainMenu2, label: 'B1'),
2629+
const DropdownMenuEntry<TestMenu>(value: TestMenu.mainMenu3, label: 'A2'),
2630+
],
2631+
),
2632+
],
2633+
),
2634+
floatingActionButton: FloatingActionButton(onPressed: () => setState(() {})),
2635+
);
2636+
},
2637+
),
2638+
),
2639+
);
2640+
2641+
// Open the menu.
2642+
await tester.tap(find.byType(DropdownMenu<TestMenu>));
2643+
await tester.pump();
2644+
2645+
// Filter the entries to only show the ones with 'A'.
2646+
await tester.enterText(find.byType(TextField), 'A');
2647+
await tester.pump();
2648+
2649+
// Select the second item in the filtered list.
2650+
await tester.tap(findMenuItemButton('A2'));
2651+
await tester.pump();
2652+
2653+
// Rebuild the widgets.
2654+
await tester.tap(find.byType(FloatingActionButton));
2655+
await tester.pump();
2656+
2657+
expect(controller.text, 'A2');
2658+
});
2659+
26022660
testWidgets('The default text input field should not be focused on mobile platforms '
26032661
'when it is tapped', (WidgetTester tester) async {
26042662
final ThemeData themeData = ThemeData();

0 commit comments

Comments
 (0)
0