-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Use case
In my use case, the DropdownMenu.dropdownMenuEntries are asynchronously fetched from the database and assigned after the Future has been resolved. The initialSelection, however, has already been set in the first build cycle.
The problem lays in that in DropdownMenu.didUpdateWidget(), where the initialSelection is not matched again against the updated menu entries. See
flutter/packages/flutter/lib/src/material/dropdown_menu.dart
Lines 552 to 557 in 9d42f82
| if (oldWidget.dropdownMenuEntries != widget.dropdownMenuEntries) { | |
| currentHighlight = null; | |
| filteredEntries = widget.dropdownMenuEntries; | |
| buttonItemKeys = List<GlobalKey>.generate(filteredEntries.length, (int index) => GlobalKey()); | |
| _menuHasEnabledItem = filteredEntries.any((DropdownMenuEntry<T> entry) => entry.enabled); | |
| } |
This will lead to an empty field not showing the matching initialSelection, but yet showing a correct list of items in the dropdown. Quite confusing...
Finding out the cause after debugging, I use the following, hopefully temporary, workaround:
DropdownMenu<String>(
initialSelection: items.isEmpty ? null : _selectedItem ?? widget.item,
... etc
)
Proposal
I would like the initialSelection to be matched again against the new value set for dropdownMenuEntries as is done when the intialSelection has changed. See
flutter/packages/flutter/lib/src/material/dropdown_menu.dart
Lines 561 to 569 in 9d42f82
| if (oldWidget.initialSelection != widget.initialSelection) { | |
| final int index = filteredEntries.indexWhere((DropdownMenuEntry<T> entry) => entry.value == widget.initialSelection); | |
| if (index != -1) { | |
| _localTextEditingController?.value = TextEditingValue( | |
| text: filteredEntries[index].label, | |
| selection: TextSelection.collapsed(offset: filteredEntries[index].label.length), | |
| ); | |
| } | |
| } |
IMHO this should be provided by Flutter directly.