From 935185ac4595ebc196166ef38622b32ddde96f3d Mon Sep 17 00:00:00 2001 From: xubaolin Date: Tue, 10 Nov 2020 05:54:02 +0800 Subject: [PATCH] Fix the PopupMenuButton offset bug (#69383) --- .../flutter/lib/src/material/popup_menu.dart | 2 +- .../test/material/popup_menu_test.dart | 40 ++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index ed95ed55d4..49022294cc 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -1053,7 +1053,7 @@ class PopupMenuButtonState extends State> { final RelativeRect position = RelativeRect.fromRect( Rect.fromPoints( button.localToGlobal(widget.offset, ancestor: overlay), - button.localToGlobal(button.size.bottomRight(Offset.zero), ancestor: overlay), + button.localToGlobal(button.size.bottomRight(Offset.zero) + widget.offset, ancestor: overlay), ), Offset.zero & overlay.size, ); diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index 1ea4fe8e62..8642e62bcc 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -759,10 +759,8 @@ void main() { }); testWidgets('Popup Menu Offset Test', (WidgetTester tester) async { - const Offset offset = Offset(100.0, 100.0); - - final PopupMenuButton popupMenuButton = - PopupMenuButton( + PopupMenuButton buildMenuButton({Offset offset = const Offset(0.0, 0.0)}) { + return PopupMenuButton( offset: offset, itemBuilder: (BuildContext context) { return >[ @@ -777,14 +775,36 @@ void main() { ]; }, ); + } + // Popup a menu without any offset. await tester.pumpWidget( MaterialApp( home: Scaffold( - body: Center( - child: Material( - child: popupMenuButton, - ), + body: Material( + child: buildMenuButton(), + ), + ), + ), + ); + + // Popup the menu. + await tester.tap(find.byType(IconButton)); + await tester.pumpAndSettle(); + + // Initial state, the menu start at Offset(8.0, 8.0), the 8 pixels is edge padding when offset.dx < 8.0. + expect(tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_PopupMenu')), const Offset(8.0, 8.0)); + + // Collapse the menu. + await tester.tap(find.byType(IconButton)); + await tester.pumpAndSettle(); + + // Popup a new menu with Offset(50.0, 50.0). + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Material( + child: buildMenuButton(offset: const Offset(50.0, 50.0)), ), ), ), @@ -793,8 +813,8 @@ void main() { await tester.tap(find.byType(IconButton)); await tester.pumpAndSettle(); - // The position is different than the offset because the default position isn't at the origin. - expect(tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_PopupMenu')), const Offset(364.0, 324.0)); + // This time the menu should start at Offset(50.0, 50.0), the padding only added when offset.dx < 8.0. + expect(tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_PopupMenu')), const Offset(50.0, 50.0)); }); testWidgets('open PopupMenu has correct semantics', (WidgetTester tester) async {