diff --git a/packages/flutter/lib/src/material/menu_anchor.dart b/packages/flutter/lib/src/material/menu_anchor.dart index 2662248bbbe..e2e602aee0c 100644 --- a/packages/flutter/lib/src/material/menu_anchor.dart +++ b/packages/flutter/lib/src/material/menu_anchor.dart @@ -26,6 +26,7 @@ import 'menu_button_theme.dart'; import 'menu_style.dart'; import 'menu_theme.dart'; import 'radio.dart'; +import 'scrollbar.dart'; import 'text_button.dart'; import 'text_theme.dart'; import 'theme.dart'; @@ -3369,6 +3370,8 @@ class _MenuPanel extends StatefulWidget { } class _MenuPanelState extends State<_MenuPanel> { + ScrollController scrollController = ScrollController(); + @override Widget build(BuildContext context) { final MenuStyle? themeStyle; @@ -3454,14 +3457,28 @@ class _MenuPanelState extends State<_MenuPanel> { clipBehavior: widget.clipBehavior, child: Padding( padding: resolvedPadding, - child: SingleChildScrollView( - scrollDirection: widget.orientation, - child: Flex( - crossAxisAlignment: CrossAxisAlignment.start, - textDirection: Directionality.of(context), - direction: widget.orientation, - mainAxisSize: MainAxisSize.min, - children: widget.children, + child: ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith( + scrollbars: false, + overscroll: false, + physics: const ClampingScrollPhysics(), + ), + child: PrimaryScrollController( + controller: scrollController, + child: Scrollbar( + thumbVisibility: true, + child: SingleChildScrollView( + controller: scrollController, + scrollDirection: widget.orientation, + child: Flex( + crossAxisAlignment: CrossAxisAlignment.start, + textDirection: Directionality.of(context), + direction: widget.orientation, + mainAxisSize: MainAxisSize.min, + children: widget.children, + ), + ), + ), ), ), ), diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart index e800005cb10..475631c2888 100644 --- a/packages/flutter/test/material/dropdown_menu_test.dart +++ b/packages/flutter/test/material/dropdown_menu_test.dart @@ -1907,6 +1907,31 @@ void main() { expect(selectionCount, 1); expect(tester.takeException(), isNull); }); + + testWidgets('Menu shows scrollbar when height is limited', (WidgetTester tester) async { + final List> menuItems = >[ + DropdownMenuEntry( + value: TestMenu.mainMenu0, + label: 'Item 0', + style: MenuItemButton.styleFrom( + minimumSize: const Size.fromHeight(1000), + ) + ), + ]; + + await tester.pumpWidget(MaterialApp( + home: Scaffold( + body: DropdownMenu( + dropdownMenuEntries: menuItems, + ), + ), + )); + + await tester.tap(find.byType(DropdownMenu)); + await tester.pumpAndSettle(); + + expect(find.byType(Scrollbar), findsOneWidget); + }, variant: TargetPlatformVariant.all()); } enum TestMenu { diff --git a/packages/flutter/test/material/menu_anchor_test.dart b/packages/flutter/test/material/menu_anchor_test.dart index 1b4eea3c871..fba85ec66f8 100644 --- a/packages/flutter/test/material/menu_anchor_test.dart +++ b/packages/flutter/test/material/menu_anchor_test.dart @@ -472,10 +472,9 @@ void main() { await tester.tap(find.text('Main Menu')); await tester.pumpAndSettle(); - expect(find.byType(Scrollbar), findsOneWidget); // Test Scrollbar thumb color. expect( - find.byType(Scrollbar), + find.byType(Scrollbar).last, paints..rrect(color: const Color(0xffff0000)), ); @@ -521,10 +520,9 @@ void main() { await tester.tap(find.text('Main Menu')); await tester.pumpAndSettle(); - expect(find.byType(Scrollbar), findsOneWidget); // Scrollbar thumb color should be updated. expect( - find.byType(Scrollbar), + find.byType(Scrollbar).last, paints..rrect(color: const Color(0xff00ff00)), ); }, variant: TargetPlatformVariant.desktop());