From 4e9869b92525a920698afc5a4abbdf02bf7a1bd0 Mon Sep 17 00:00:00 2001 From: Mahdi Bagheri <53684884+mhbdev@users.noreply.github.com> Date: Fri, 9 Jun 2023 01:55:38 +0330 Subject: [PATCH] Navigator.pop before PopupMenuItem onTap call (#127446) *The order of calling Navigator.pop and PopupMenuItem.onTap has been changed so before calling PopupMenuItem onTap method, PopupMenuBotton onSelect method is going to be called.* *Solves #127443* *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* --- .../flutter/lib/src/material/popup_menu.dart | 5 ++- .../test/material/popup_menu_test.dart | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index a5db27efa4..afc0de1144 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -339,9 +339,10 @@ class PopupMenuItemState> extends State { /// the menu route. @protected void handleTap() { - widget.onTap?.call(); - + // Need to pop the navigator first in case onTap may push new route onto navigator. Navigator.pop(context, widget.value); + + widget.onTap?.call(); } @override diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index a037285242..fda95a5b4d 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -3260,6 +3260,48 @@ void main() { final Offset menuTopLeft = tester.getTopLeft(find.bySemanticsLabel('Popup menu')); expect(childBottomLeft, menuTopLeft); }); + + testWidgets('PopupmenuItem onTap should be calling after Navigator.pop', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + appBar: AppBar( + actions: [ + PopupMenuButton( + itemBuilder: (BuildContext context) => >[ + PopupMenuItem( + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return const SizedBox( + height: 200.0, + child: Center(child: Text('ModalBottomSheet')), + ); + }, + ); + }, + value: 10, + child: const Text('ACTION'), + ), + ], + ), + ], + ), + ), + ), + ); + + await tester.tap(find.byType(PopupMenuButton)); + await tester.pumpAndSettle(); + + await tester.tap(find.text('ACTION')); + await tester.pumpAndSettle(); + + // Verify that the ModalBottomSheet is displayed + final Finder modalBottomSheet = find.text('ModalBottomSheet'); + expect(modalBottomSheet, findsOneWidget); + }); } class TestApp extends StatelessWidget {