Home > Mobile >  showDialog bug: dialog isn't triggered from PopupMenuButton in Flutter
showDialog bug: dialog isn't triggered from PopupMenuButton in Flutter

Time:11-12

I am not able to get showDialog work with PopupMenuButton. In the example below, there is a button with triggering a dialog to display and a popupmenu too triggering a dialog to display.

The button works but on clicking on the Alert text in PopupMenu, the same doesn't happen.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('showDialog bug'), actions: [
          PopupMenuButton(
              itemBuilder: (ctx) => [
                    PopupMenuItem(
                        child: Text('Alert'),
                        onTap: () {
                          showDialog(
                              context: context,
                              builder: (ctx) => AlertDialog(
                                    title: Text('test dialog'),
                                  ));
                        })
                  ])
        ]),
        body: ElevatedButton(
            onPressed: () {
              showDialog(
                  context: context,
                  builder: (ctx) => AlertDialog(
                        title: Text('test dialog'),
                      ));
            },
            child: Text('click me')));
  }
}

However, when I add another block of showDialog subsequent to it, it starts working.

showDialog(
context: context,
builder: (ctx) => AlertDialog(
      title: Text('test dialog'),
    ));

CodePudding user response:

It's not a bug. As I remember, the "onTap" callback of PopupMenuItem calls Navigator.pop to close the Popup. In that case, when you tap on the PopupMenuItem and call "showDialog", the dialog will be popped immediately, and leaves the Popup open.

In order to overcome that, you may try this solution :

PopupMenuItem(
             child: const Text('Alert'),
              onTap: () {
                Future.delayed(
                    const Duration(seconds: 0),
                    () => showDialog(
                          context: context,
                          builder: (context) => const AlertDialog(
                            title: Text('test dialog'),
                          ),
                        ));
              },
            )
  • Related