diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart index ca666d9254..6bca05aa3e 100644 --- a/packages/flutter/lib/src/material/dropdown_menu.dart +++ b/packages/flutter/lib/src/material/dropdown_menu.dart @@ -521,18 +521,6 @@ class _DropdownMenuState extends State> { TextEditingController? _localTextEditingController; final FocusNode _internalFocudeNode = FocusNode(); - TextEditingValue get _initialTextEditingValue { - for (final DropdownMenuEntry entry in filteredEntries) { - if (entry.value == widget.initialSelection) { - return TextEditingValue( - text: entry.label, - selection: TextSelection.collapsed(offset: entry.label.length), - ); - } - } - return TextEditingValue.empty; - } - @override void initState() { super.initState(); @@ -545,8 +533,15 @@ class _DropdownMenuState extends State> { filteredEntries = widget.dropdownMenuEntries; buttonItemKeys = List.generate(filteredEntries.length, (int index) => GlobalKey()); _menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry entry) => entry.enabled); - _localTextEditingController?.value = _initialTextEditingValue; - + final int index = filteredEntries.indexWhere( + (DropdownMenuEntry entry) => entry.value == widget.initialSelection, + ); + if (index != -1) { + _localTextEditingController?.value = TextEditingValue( + text: filteredEntries[index].label, + selection: TextSelection.collapsed(offset: filteredEntries[index].label.length), + ); + } refreshLeadingPadding(); } @@ -585,19 +580,20 @@ class _DropdownMenuState extends State> { filteredEntries = widget.dropdownMenuEntries; buttonItemKeys = List.generate(filteredEntries.length, (int index) => GlobalKey()); _menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry entry) => entry.enabled); - // If the text field content matches one of the new entries do not rematch the initialSelection. - final bool isCurrentSelectionValid = filteredEntries.any( - (DropdownMenuEntry entry) => entry.label == _localTextEditingController?.text, - ); - if (!isCurrentSelectionValid) { - _localTextEditingController?.value = _initialTextEditingValue; - } } if (oldWidget.leadingIcon != widget.leadingIcon) { refreshLeadingPadding(); } if (oldWidget.initialSelection != widget.initialSelection) { - _localTextEditingController?.value = _initialTextEditingValue; + final int index = filteredEntries.indexWhere( + (DropdownMenuEntry entry) => entry.value == widget.initialSelection, + ); + if (index != -1) { + _localTextEditingController?.value = TextEditingValue( + text: filteredEntries[index].label, + selection: TextSelection.collapsed(offset: filteredEntries[index].label.length), + ); + } } } diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart index 0591507705..508d1d9af0 100644 --- a/packages/flutter/test/material/dropdown_menu_test.dart +++ b/packages/flutter/test/material/dropdown_menu_test.dart @@ -2174,83 +2174,30 @@ void main() { expect(controller.text, isEmpty); }); - // Regression test for https://github.com/flutter/flutter/issues/155660. - testWidgets('Updating the menu entries refreshes the initial selection', ( - WidgetTester tester, - ) async { - final TextEditingController controller = TextEditingController(); - addTearDown(controller.dispose); - - Widget boilerplate(List> entries) { - return MaterialApp( - home: StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return Scaffold( - body: DropdownMenu( - initialSelection: TestMenu.mainMenu3, - dropdownMenuEntries: entries, - controller: controller, - ), - ); - }, - ), - ); - } - - // The text field should be empty when the initial selection does not match - // any menu items. - await tester.pumpWidget(boilerplate(menuChildren.getRange(0, 1).toList())); - expect(controller.text, ''); - - // When the menu entries is updated the initial selection should be rematched. - await tester.pumpWidget(boilerplate(menuChildren)); - expect(controller.text, TestMenu.mainMenu3.label); - - // Update the entries with none matching the initial selection. - await tester.pumpWidget(boilerplate(menuChildren.getRange(0, 1).toList())); - expect(controller.text, ''); - }); - - // Regression test for https://github.com/flutter/flutter/issues/155660. testWidgets( - 'Updating the menu entries refreshes the initial selection only if the current selection is no more valid', + 'Text field content is not cleared when the initial selection does not match any menu entries', (WidgetTester tester) async { - final TextEditingController controller = TextEditingController(); + final TextEditingController controller = TextEditingController(text: 'Flutter'); addTearDown(controller.dispose); - Widget boilerplate(List> entries) { - return MaterialApp( + await tester.pumpWidget( + MaterialApp( home: StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return Scaffold( body: DropdownMenu( initialSelection: TestMenu.mainMenu3, - dropdownMenuEntries: entries, + // Use a menu entries which does not contain TestMenu.mainMenu3. + dropdownMenuEntries: menuChildren.getRange(0, 1).toList(), controller: controller, ), ); }, ), - ); - } + ), + ); - await tester.pumpWidget(boilerplate(menuChildren)); - expect(controller.text, TestMenu.mainMenu3.label); - - // Open the menu. - await tester.tap(find.byType(DropdownMenu)); - await tester.pump(); - - // Select another item. - final Finder item2 = findMenuItemButton('Item 2'); - await tester.tap(item2); - await tester.pumpAndSettle(); - expect(controller.text, TestMenu.mainMenu2.label); - - // Update the menu entries with another instance of list containing the - // same entries. - await tester.pumpWidget(boilerplate(List>.from(menuChildren))); - expect(controller.text, TestMenu.mainMenu2.label); + expect(controller.text, 'Flutter'); }, );