Flutter - Navigate in PopupMenuButton onTap does not work

853

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

Share:
853
finisinfinitatis
Author by

finisinfinitatis

Updated on January 01, 2023

Comments

  • finisinfinitatis
    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
      TheMisplacedMechEngineer over 2 years
      Can you try passing the context from the itemBuilder into _openSettings()? So you can pass the correct context to the Navigator
  • finisinfinitatis
    finisinfinitatis over 2 years
    The 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
    Hooshyar over 2 years
    I added the code where the issue has been fixed.
  • finisinfinitatis
    finisinfinitatis over 2 years
    Thanks, 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
    Kay over 2 years
    I just figured out that its already enough to await 1 millisecond