Unverified Commit be8a1eac authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

Add scrollbar for menus (#140941)

Fixes #140162

This PR is to add a scrollbar for MenuAnchor and DropdownMenu for all platforms when height is limited. Previously, a scrollbar only shows on desktop platforms. This PR also disabled scrollbar's overscroll for MenuAnchor and DropdownMenu.

<img src="https://github.com/flutter/flutter/assets/36861262/9ca3d4d0-415f-43bf-9d2b-df96a42db620" width="250"/><img src="https://github.com/flutter/flutter/assets/36861262/18da8d02-586b-4aa4-b647-927691542429" width="350"/>
parent e256d491
......@@ -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,
),
),
),
),
),
),
......
......@@ -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<DropdownMenuEntry<TestMenu>> menuItems = <DropdownMenuEntry<TestMenu>>[
DropdownMenuEntry<TestMenu>(
value: TestMenu.mainMenu0,
label: 'Item 0',
style: MenuItemButton.styleFrom(
minimumSize: const Size.fromHeight(1000),
)
),
];
await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: DropdownMenu<TestMenu>(
dropdownMenuEntries: menuItems,
),
),
));
await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pumpAndSettle();
expect(find.byType(Scrollbar), findsOneWidget);
}, variant: TargetPlatformVariant.all());
}
enum TestMenu {
......
......@@ -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());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment