@@ -102,9 +102,11 @@ class _DropdownMenuItemButton<T> extends StatefulWidget {
102102 required this .constraints,
103103 required this .itemIndex,
104104 required this .enableFeedback,
105+ required this .scrollController,
105106 });
106107
107108 final _DropdownRoute <T > route;
109+ final ScrollController scrollController;
108110 final EdgeInsets ? padding;
109111 final Rect buttonRect;
110112 final BoxConstraints constraints;
@@ -131,7 +133,7 @@ class _DropdownMenuItemButtonState<T> extends State<_DropdownMenuItemButton<T>>
131133 widget.constraints.maxHeight,
132134 widget.itemIndex,
133135 );
134- widget.route. scrollController! .animateTo (
136+ widget.scrollController.animateTo (
135137 menuLimits.scrollOffset,
136138 curve: Curves .easeInOut,
137139 duration: const Duration (milliseconds: 100 ),
@@ -205,6 +207,7 @@ class _DropdownMenu<T> extends StatefulWidget {
205207 this .dropdownColor,
206208 required this .enableFeedback,
207209 this .borderRadius,
210+ required this .scrollController,
208211 });
209212
210213 final _DropdownRoute <T > route;
@@ -214,6 +217,7 @@ class _DropdownMenu<T> extends StatefulWidget {
214217 final Color ? dropdownColor;
215218 final bool enableFeedback;
216219 final BorderRadius ? borderRadius;
220+ final ScrollController scrollController;
217221
218222 @override
219223 _DropdownMenuState <T > createState () => _DropdownMenuState <T >();
@@ -264,6 +268,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
264268 constraints: widget.constraints,
265269 itemIndex: itemIndex,
266270 enableFeedback: widget.enableFeedback,
271+ scrollController: widget.scrollController,
267272 ),
268273 ];
269274
@@ -304,7 +309,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
304309 platform: Theme .of (context).platform,
305310 ),
306311 child: PrimaryScrollController (
307- controller: widget.route. scrollController! ,
312+ controller: widget.scrollController,
308313 child: Scrollbar (
309314 thumbVisibility: true ,
310315 child: ListView (
@@ -447,7 +452,6 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
447452 final BorderRadius ? borderRadius;
448453
449454 final List <double > itemHeights;
450- ScrollController ? scrollController;
451455
452456 @override
453457 Duration get transitionDuration => _kDropdownMenuDuration;
@@ -572,7 +576,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
572576 }
573577}
574578
575- class _DropdownRoutePage <T > extends StatelessWidget {
579+ class _DropdownRoutePage <T > extends StatefulWidget {
576580 const _DropdownRoutePage ({
577581 super .key,
578582 required this .route,
@@ -603,29 +607,41 @@ class _DropdownRoutePage<T> extends StatelessWidget {
603607 final BorderRadius ? borderRadius;
604608
605609 @override
606- Widget build (BuildContext context) {
607- assert (debugCheckHasDirectionality (context));
610+ State <_DropdownRoutePage <T >> createState () => _DropdownRoutePageState <T >();
611+ }
612+
613+ class _DropdownRoutePageState <T > extends State <_DropdownRoutePage <T >> {
614+ late ScrollController _scrollSontroller;
615+
616+ @override
617+ void initState (){
618+ super .initState ();
608619
609620 // Computing the initialScrollOffset now, before the items have been laid
610621 // out. This only works if the item heights are effectively fixed, i.e. either
611622 // DropdownButton.itemHeight is specified or DropdownButton.itemHeight is null
612623 // and all of the items' intrinsic heights are less than kMinInteractiveDimension.
613624 // Otherwise the initialScrollOffset is just a rough approximation based on
614625 // treating the items as if their heights were all equal to kMinInteractiveDimension.
615- if (route.scrollController == null ) {
616- final _MenuLimits menuLimits = route.getMenuLimits (buttonRect, constraints.maxHeight, selectedIndex);
617- route.scrollController = ScrollController (initialScrollOffset: menuLimits.scrollOffset);
618- }
626+ final _MenuLimits menuLimits = widget.route.getMenuLimits (widget.buttonRect, widget.constraints.maxHeight, widget.selectedIndex);
627+ _scrollSontroller = ScrollController (initialScrollOffset: menuLimits.scrollOffset);
628+ }
629+
630+
631+ @override
632+ Widget build (BuildContext context) {
633+ assert (debugCheckHasDirectionality (context));
619634
620635 final TextDirection ? textDirection = Directionality .maybeOf (context);
621636 final Widget menu = _DropdownMenu <T >(
622- route: route,
623- padding: padding.resolve (textDirection),
624- buttonRect: buttonRect,
625- constraints: constraints,
626- dropdownColor: dropdownColor,
627- enableFeedback: enableFeedback,
628- borderRadius: borderRadius,
637+ route: widget.route,
638+ padding: widget.padding.resolve (textDirection),
639+ buttonRect: widget.buttonRect,
640+ constraints: widget.constraints,
641+ dropdownColor: widget.dropdownColor,
642+ enableFeedback: widget.enableFeedback,
643+ borderRadius: widget.borderRadius,
644+ scrollController: _scrollSontroller,
629645 );
630646
631647 return MediaQuery .removePadding (
@@ -638,16 +654,22 @@ class _DropdownRoutePage<T> extends StatelessWidget {
638654 builder: (BuildContext context) {
639655 return CustomSingleChildLayout (
640656 delegate: _DropdownMenuRouteLayout <T >(
641- buttonRect: buttonRect,
642- route: route,
657+ buttonRect: widget. buttonRect,
658+ route: widget. route,
643659 textDirection: textDirection,
644660 ),
645- child: capturedThemes.wrap (menu),
661+ child: widget. capturedThemes.wrap (menu),
646662 );
647663 },
648664 ),
649665 );
650666 }
667+
668+ @override
669+ void dispose () {
670+ _scrollSontroller.dispose ();
671+ super .dispose ();
672+ }
651673}
652674
653675// This widget enables _DropdownRoute to look up the sizes of
0 commit comments