Flutter - Navigate in PopupMenuButton onTap does not work
I had the same issue (except: I am using GetX for Navigation.
I think this happens because flutter is closing the PopupMenuButton automatically and because navigation happens to fast, it closes the new route instead of the menuButton.
I solved it like this in the navigating method:
void edit() async {
await Future.delayed(const Duration(milliseconds: 10));
Get.toNamed('/new/route'); // same like Navigator.of(context).pushNamed()
}
It's not beautiful... i know. But it works XD
finisinfinitatis
Updated on January 01, 2023Comments
-
finisinfinitatis over 1 year
I used to use IconButton's onpressed to navigate to the settings page from my AppBar which worked. Now I am trying to trigger the navigation from a PopupMenuItem's onTap but the page does not navigate. Both widgets are in the same hierarchy and I can't find out the reason for the different behavior. No error is thrown.
Here is the code of my appBar which contains the actions:
Widget build(BuildContext ctx) { return Container( child: Scaffold( appBar: AppBar( title: const Text('MyApp'), actions: [ PopupMenuButton( itemBuilder: (context) => [ // THE NAVIGATION IN onTap DOES NOT WORK PopupMenuItem( child: Text(AppLocalizations.of(context).settings), onTap: () => _openSettings(ctx), ), ], icon: Icon( Icons.settings, ), ), // THIS WORKS IconButton(onPressed: () => _openSettings(ctx), icon: Icon(Icons.settings)) ], ), body: Text("") ), ); }
And here the function whose navigation call only works inside IconButton's onpressed. I could confirm that the function was triggered in both cases though:
Future<void> _openSettings(BuildContext ctx) async { print('settings'); await Navigator.push( ctx, MaterialPageRoute(builder: (ctx) => SettingsPage())); print('settings completed'); }
I'd appreciate any help!
Workaround: I have not found out what the issue with onTap navigation is but now I am just using onSelected which results in the same UX and works:
Widget build(BuildContext ctx) { return Container( child: Scaffold( appBar: AppBar( title: const Text('MyApp'), actions: [ PopupMenuButton( onSelected: (result){ switch(result){ case 0: _openSettings(); break; case 1: _signOut(); break; } }, itemBuilder: (context) => [ PopupMenuItem( child: Text(AppLocalizations.of(context).settings), value: 0 ), PopupMenuItem( child: Text(AppLocalizations.of(context).logout), value: 1 ) ], icon: Icon( Icons.settings, ), ) ], ) ) ); }
-
TheMisplacedMechEngineer over 2 yearsCan you try passing the
context
from theitemBuilder
into_openSettings()
? So you can pass the correctcontext
to the Navigator
-
-
finisinfinitatis over 2 yearsThe call from onPressed worked before already. I applied the changes you proposed to the call in PopupMenuItem but the navigation after the onTap call still does not work unfortunately.
-
Hooshyar over 2 yearsI added the code where the issue has been fixed.
-
finisinfinitatis over 2 yearsThanks, this works for me as well. The problem is when I add the _openSettings call to the PopupMenuItem (like here: PopupMenuItem( child: Text(AppLocalizations.of(context).settings), onTap: ()=>_openSettings(ctx), )) is does not work anymore.
-
Kay over 2 yearsI just figured out that its already enough to await 1 millisecond