Fix DropdownMenu filtering is broken (#177450)

## Description

This PR fixes `DropdownMenu` filtering.
This is mainly a revert of
https://github.com/flutter/flutter/pull/162062.
It adds a test to avoid a similar regression in the future.

It will reeopen https://github.com/flutter/flutter/issues/155660. A
future PR will try to fix that issue.

See
https://github.com/flutter/flutter/pull/174757#issuecomment-3430614390
for more context.

## Related Issue

Fixes [DropdownMenu filtering is
broken](https://github.com/flutter/flutter/issues/174609)
Reeopens [DropdownMenu.didUpdateWidget should re-match initialSelection
when dropdownMenuEntries have
changed](https://github.com/flutter/flutter/issues/155660)

## Tests

Adds 1 test.
Removes 3 tests (reverted tests from
https://github.com/flutter/flutter/pull/162062).
diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart
index 3d2dfe7..ddaebc0 100644
--- a/packages/flutter/lib/src/material/dropdown_menu.dart
+++ b/packages/flutter/lib/src/material/dropdown_menu.dart
@@ -662,8 +662,6 @@
   TextEditingController get _effectiveTextEditingController =>
       widget.controller ?? (_localTextEditingController ??= TextEditingController());
   final FocusNode _internalFocudeNode = FocusNode();
-  int? _selectedEntryIndex;
-  late final void Function() _clearSelectedEntryIndex;
 
   FocusNode? _localTrailingIconButtonFocusNode;
   FocusNode get _trailingIconButtonFocusNode =>
@@ -672,8 +670,6 @@
   @override
   void initState() {
     super.initState();
-    _clearSelectedEntryIndex = () => _selectedEntryIndex = null;
-    _effectiveTextEditingController.addListener(_clearSelectedEntryIndex);
     _enableSearch = widget.enableSearch;
     filteredEntries = widget.dropdownMenuEntries;
     buttonItemKeys = List<GlobalKey>.generate(filteredEntries.length, (int index) => GlobalKey());
@@ -686,7 +682,6 @@
         text: filteredEntries[index].label,
         selection: TextSelection.collapsed(offset: filteredEntries[index].label.length),
       );
-      _selectedEntryIndex = index;
     }
     refreshLeadingPadding();
     _controller = widget.menuController ?? MenuController();
@@ -694,7 +689,6 @@
 
   @override
   void dispose() {
-    widget.controller?.removeListener(_clearSelectedEntryIndex);
     _localTextEditingController?.dispose();
     _localTextEditingController = null;
     _internalFocudeNode.dispose();
@@ -707,11 +701,8 @@
   void didUpdateWidget(DropdownMenu<T> oldWidget) {
     super.didUpdateWidget(oldWidget);
     if (oldWidget.controller != widget.controller) {
-      oldWidget.controller?.removeListener(_clearSelectedEntryIndex);
       _localTextEditingController?.dispose();
       _localTextEditingController = null;
-      _effectiveTextEditingController.addListener(_clearSelectedEntryIndex);
-      _selectedEntryIndex = null;
     }
     if (oldWidget.enableFilter != widget.enableFilter) {
       if (!widget.enableFilter) {
@@ -729,21 +720,6 @@
       filteredEntries = widget.dropdownMenuEntries;
       buttonItemKeys = List<GlobalKey>.generate(filteredEntries.length, (int index) => GlobalKey());
       _menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry<T> entry) => entry.enabled);
-      if (_selectedEntryIndex != null) {
-        final T oldSelectionValue = oldWidget.dropdownMenuEntries[_selectedEntryIndex!].value;
-        final int index = filteredEntries.indexWhere(
-          (DropdownMenuEntry<T> entry) => entry.value == oldSelectionValue,
-        );
-        if (index != -1) {
-          _effectiveTextEditingController.value = TextEditingValue(
-            text: filteredEntries[index].label,
-            selection: TextSelection.collapsed(offset: filteredEntries[index].label.length),
-          );
-          _selectedEntryIndex = index;
-        } else {
-          _selectedEntryIndex = null;
-        }
-      }
     }
     if (oldWidget.leadingIcon != widget.leadingIcon) {
       refreshLeadingPadding();
@@ -757,7 +733,6 @@
           text: filteredEntries[index].label,
           selection: TextSelection.collapsed(offset: filteredEntries[index].label.length),
         );
-        _selectedEntryIndex = index;
       }
     }
     if (oldWidget.menuController != widget.menuController) {
@@ -963,7 +938,6 @@
                     text: entry.label,
                     selection: TextSelection.collapsed(offset: entry.label.length),
                   );
-                  _selectedEntryIndex = i;
                   currentHighlight = widget.enableSearch ? i : null;
                   widget.onSelected?.call(entry.value);
                   _enableFilter = false;
@@ -1056,7 +1030,6 @@
           text: entry.label,
           selection: TextSelection.collapsed(offset: entry.label.length),
         );
-        _selectedEntryIndex = currentHighlight;
         widget.onSelected?.call(entry.value);
       }
     } else {
diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart
index 5f19b26..e3ca967 100644
--- a/packages/flutter/test/material/dropdown_menu_test.dart
+++ b/packages/flutter/test/material/dropdown_menu_test.dart
@@ -2479,178 +2479,6 @@
     },
   );
 
-  testWidgets('Rematch selection against the first entry with the same value', (
-    WidgetTester tester,
-  ) async {
-    final TextEditingController controller = TextEditingController();
-    addTearDown(controller.dispose);
-
-    String selectionLabel = 'Initial label';
-
-    await tester.pumpWidget(
-      MaterialApp(
-        home: StatefulBuilder(
-          builder: (BuildContext context, StateSetter setState) {
-            return Scaffold(
-              body: DropdownMenu<TestMenu>(
-                initialSelection: TestMenu.mainMenu0,
-                dropdownMenuEntries: <DropdownMenuEntry<TestMenu>>[
-                  DropdownMenuEntry<TestMenu>(
-                    value: TestMenu.mainMenu0,
-                    label: '$selectionLabel 0',
-                  ),
-                  DropdownMenuEntry<TestMenu>(
-                    value: TestMenu.mainMenu1,
-                    label: '$selectionLabel 1',
-                  ),
-                ],
-                controller: controller,
-              ),
-              floatingActionButton: FloatingActionButton(
-                onPressed: () => setState(() => selectionLabel = 'Updated label'),
-              ),
-            );
-          },
-        ),
-      ),
-    );
-
-    // Open the menu
-    await tester.tap(find.byType(DropdownMenu<TestMenu>));
-    await tester.pump();
-
-    // Select the second item
-    await tester.tap(findMenuItemButton('$selectionLabel 1'));
-    await tester.pump();
-
-    // Update dropdownMenuEntries labels
-    await tester.tap(find.byType(FloatingActionButton));
-    await tester.pump();
-
-    expect(controller.text, 'Updated label 1');
-  });
-
-  testWidgets('Forget selection if its value does not map to any entry', (
-    WidgetTester tester,
-  ) async {
-    final TextEditingController controller = TextEditingController();
-    addTearDown(controller.dispose);
-
-    String selectionLabel = 'Initial label';
-    bool selectionInEntries = true;
-
-    await tester.pumpWidget(
-      MaterialApp(
-        home: StatefulBuilder(
-          builder: (BuildContext context, StateSetter setState) {
-            return Scaffold(
-              body: Column(
-                children: <Widget>[
-                  DropdownMenu<TestMenu>(
-                    initialSelection: TestMenu.mainMenu0,
-                    dropdownMenuEntries: <DropdownMenuEntry<TestMenu>>[
-                      DropdownMenuEntry<TestMenu>(
-                        value: TestMenu.mainMenu0,
-                        label: '$selectionLabel 0',
-                      ),
-                      if (selectionInEntries)
-                        DropdownMenuEntry<TestMenu>(
-                          value: TestMenu.mainMenu1,
-                          label: '$selectionLabel 1',
-                        ),
-                    ],
-                    controller: controller,
-                  ),
-                  ElevatedButton(
-                    onPressed: () => setState(() => selectionInEntries = !selectionInEntries),
-                    child: null,
-                  ),
-                ],
-              ),
-              floatingActionButton: FloatingActionButton(
-                onPressed: () => setState(() => selectionLabel = 'Updated label'),
-              ),
-            );
-          },
-        ),
-      ),
-    );
-
-    // Open the menu
-    await tester.tap(find.byType(DropdownMenu<TestMenu>));
-    await tester.pump();
-
-    // Select the second item
-    await tester.tap(findMenuItemButton('$selectionLabel 1'));
-    await tester.pump();
-
-    // Update dropdownMenuEntries labels
-    await tester.tap(find.byType(FloatingActionButton));
-    // Remove second item from entires
-    await tester.tap(find.byType(ElevatedButton));
-    await tester.pump();
-
-    expect(controller.text, 'Initial label 1');
-
-    // Put second item back into entries
-    await tester.tap(find.byType(ElevatedButton));
-    await tester.pump();
-
-    expect(controller.text, 'Initial label 1');
-  });
-
-  testWidgets(
-    'Do not rematch selection if the text field was edited progrmaticlly via controller',
-    (WidgetTester tester) async {
-      final TextEditingController controller = TextEditingController();
-      addTearDown(controller.dispose);
-
-      String selectionLabel = 'Initial label';
-
-      await tester.pumpWidget(
-        MaterialApp(
-          home: StatefulBuilder(
-            builder: (BuildContext context, StateSetter setState) {
-              return Scaffold(
-                body: Column(
-                  children: <Widget>[
-                    DropdownMenu<TestMenu>(
-                      initialSelection: TestMenu.mainMenu0,
-                      dropdownMenuEntries: <DropdownMenuEntry<TestMenu>>[
-                        DropdownMenuEntry<TestMenu>(
-                          value: TestMenu.mainMenu0,
-                          label: '$selectionLabel 0',
-                        ),
-                      ],
-                      controller: controller,
-                    ),
-                    ElevatedButton(
-                      onPressed: () => setState(() => controller.text = 'Controller Value'),
-                      child: null,
-                    ),
-                  ],
-                ),
-                floatingActionButton: FloatingActionButton(
-                  onPressed: () => setState(() => selectionLabel = 'Updated label'),
-                ),
-              );
-            },
-          ),
-        ),
-      );
-
-      // Change the text field value via controller
-      await tester.tap(find.byType(ElevatedButton));
-      await tester.pump();
-
-      // Update dropdownMenuEntries labels
-      await tester.tap(find.byType(FloatingActionButton));
-      await tester.pump();
-
-      expect(controller.text, 'Controller Value');
-    },
-  );
-
   testWidgets('The default text input field should not be focused on mobile platforms '
       'when it is tapped', (WidgetTester tester) async {
     final ThemeData themeData = ThemeData();
@@ -4981,6 +4809,50 @@
       }, throwsAssertionError);
     });
   });
+
+  // Regression test for https://github.com/flutter/flutter/issues/174609.
+  testWidgets(
+    'DropdownMenu keeps the selected item from filtered list after entries list is updated',
+    (WidgetTester tester) async {
+      final TextEditingController controller = TextEditingController();
+      addTearDown(controller.dispose);
+
+      await tester.pumpWidget(
+        MaterialApp(
+          home: Scaffold(
+            body: StatefulBuilder(
+              builder: (BuildContext context, StateSetter setState) {
+                return DropdownMenu<TestMenu>(
+                  controller: controller,
+                  requestFocusOnTap: true,
+                  enableFilter: true,
+                  // toList() is used here to simulate list update.
+                  dropdownMenuEntries: menuChildren.toList(),
+                  onSelected: (_) {
+                    setState(() {});
+                  },
+                );
+              },
+            ),
+          ),
+        ),
+      );
+
+      // Open the menu.
+      await tester.tap(find.byType(DropdownMenu<TestMenu>));
+      await tester.pump();
+
+      // Filter the entries to only show 'Menu 1'.
+      await tester.enterText(find.byType(TextField).first, TestMenu.mainMenu1.label);
+      await tester.pump();
+
+      // Select the 'Menu 1' item.
+      await tester.tap(findMenuItemButton(TestMenu.mainMenu1.label));
+      await tester.pumpAndSettle();
+
+      expect(controller.text, TestMenu.mainMenu1.label);
+    },
+  );
 }
 
 enum TestMenu {