@@ -19,11 +19,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
1919 required this .menuItemStyle,
2020 required this .searchData,
2121 this .dropdownSeparator,
22- }) : itemHeights = addSeparatorsHeights (
23- itemHeights: items.map ((item) => item.height).toList (),
24- separatorHeight: dropdownSeparator? .height,
25- ),
26- barrierColor = barrierCoversButton ? barrierColor : null ,
22+ }) : barrierColor = barrierCoversButton ? barrierColor : null ,
2723 _altBarrierColor = barrierColor;
2824
2925 final List <DropdownItem <T >> items;
@@ -40,7 +36,6 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
4036 final DropdownSearchData <T >? searchData;
4137 final DropdownSeparator <T >? dropdownSeparator;
4238
43- final List <double > itemHeights;
4439 ScrollController ? scrollController;
4540
4641 @override
@@ -114,17 +109,32 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
114109 }
115110 }
116111
112+ double _itemHeightWithSeparator (int itemIndex) {
113+ final itemHeight = items[itemIndex].height;
114+ final separatorHeight = dropdownSeparator? .height ?? 0 ;
115+ return itemIndex != 0 ? itemHeight + separatorHeight : itemHeight;
116+ }
117+
118+ double _calculateHeightUntilIndex (
119+ int index, {
120+ bool Function (DropdownItem <T > item)? itemPredicate,
121+ }) {
122+ var itemsHeight = 0.0 ;
123+ for (int i = 0 ; i < index; i++ ) {
124+ if (itemPredicate == null || itemPredicate (items[i])) {
125+ itemsHeight += _itemHeightWithSeparator (i);
126+ }
127+ }
128+ return itemsHeight;
129+ }
130+
117131 double getItemOffset (int index) {
118132 final double paddingTop = dropdownStyle.padding != null
119133 ? dropdownStyle.padding! .resolve (null ).top
120134 : kMaterialListPadding.top;
121135 double offset = paddingTop;
122136
123137 if (items.isNotEmpty && index > 0 ) {
124- assert (
125- items.length + (dropdownSeparator != null ? items.length - 1 : 0 ) ==
126- itemHeights.length,
127- );
128138 if (searchData? .searchController? .text case final searchText? ) {
129139 final searchMatchFn =
130140 searchData? .searchMatchFn ?? _defaultSearchMatchFn ();
@@ -133,24 +143,19 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
133143 offset += _getSearchItemsHeight (index, searchText);
134144 }
135145 } else {
136- for (int i = 0 ; i < index; i++ ) {
137- offset += itemHeights[i];
138- }
146+ offset += _calculateHeightUntilIndex (index);
139147 }
140148 }
141149
142150 return offset;
143151 }
144152
145153 double _getSearchItemsHeight (int index, String searchText) {
146- var itemsHeight = 0.0 ;
147154 final searchMatchFn = searchData? .searchMatchFn ?? _defaultSearchMatchFn ();
148- for (int i = 0 ; i < index; i++ ) {
149- if (searchMatchFn (items[i], searchText)) {
150- itemsHeight += itemHeights[i];
151- }
152- }
153- return itemsHeight;
155+ return _calculateHeightUntilIndex (
156+ index,
157+ itemPredicate: (item) => searchMatchFn (item, searchText),
158+ );
154159 }
155160
156161 // Returns the vertical extent of the menu and the initial scrollOffset
@@ -177,7 +182,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
177182 final searchText = searchData? .searchController? .text;
178183 actualMenuHeight += searchText != null
179184 ? _getSearchItemsHeight (items.length, searchText)
180- : itemHeights. reduce (( double total, double height) => total + height );
185+ : _calculateHeightUntilIndex (items.length );
181186 }
182187
183188 // Use actualMenuHeight if it's less than maxHeight.
@@ -215,13 +220,11 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
215220 final double actualMenuNetHeight = actualMenuHeight - innerWidgetHeight;
216221 // The offset should be zero if the selected item is in view at the beginning
217222 // of the menu. Otherwise, the scroll offset should center the item if possible.
218- final actualIndex = dropdownSeparator? .height != null ? index * 2 : index;
219- final double selectedItemOffset = getItemOffset (actualIndex);
223+ final double selectedItemOffset = getItemOffset (index);
220224 scrollOffset = math.max (
221- 0.0 ,
222- selectedItemOffset -
223- (menuNetHeight / 2 ) +
224- (itemHeights[actualIndex] / 2 ));
225+ 0.0 ,
226+ selectedItemOffset - (menuNetHeight / 2 ) + (items[index].height / 2 ),
227+ );
225228 // If the selected item's scroll offset is greater than the maximum scroll offset,
226229 // set it instead to the maximum allowed scroll offset.
227230 final double maxScrollOffset = actualMenuNetHeight - menuNetHeight;
0 commit comments