flutterpopupmenubutton

Flutter bug with PopupMenuButton and TextFiend inside AlertDialog


I have an AlertDialog that contains a TextField and a PopupMenuButton. When the TextField has focus and the keyboard is open, the AlertDialog is in a "raised" position, but if I press the PopupMenuButton, the TextField get unfocus, and the animations of the AlertDialog "going down" (because the keyboard disappeard) and the PopupMenuButton opening start togheter, and result in a wrong position of PopupMenuItems. How can I solve this?

I tried to edit the PopupMenuButton class but I don't know how to wait until the AlertDialog is repositioned to show the popup menu.

This is a sample of code that replicate the problem

return AlertDialog(
  content: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      TextField(),
      PopupMenuButton(itemBuilder: (BuildContext context)=>[PopupMenuItem(child: Text('123')),PopupMenuItem(child: Text('456'))])
    ],
  ),
);

This is a gif showing the bug: https://i.sstatic.net/dNjq1.gif


Solution

  • after getting some hours for researching that was PopupMenuButton normal behaviour, when I tried to recreate the PopupMenuButton manually, it work as that because when clicked it get the first position of the below menubutton so when i recreate it, it look like this

    class TestWidget extends StatefulWidget {
      @override
      _TestWidgetState createState() => _TestWidgetState();
    }
    
    class _TestWidgetState extends State<TestWidget> {
      void _showPopupMenu(Offset offset) async {
        double left = offset.dx;
        double top = offset.dy;
        await showMenu(
          context: context,
          position: RelativeRect.fromLTRB(left, top, 0, 0),
          items: [
            const PopupMenuItem<String>(value: 'Doge', child: Text('Doge')),
            const PopupMenuItem<String>(value: 'Lion', child: Text('Lion')),
          ],
          elevation: 8.0,
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return AlertDialog(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const TextField(),
              GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTapDown: (TapDownDetails details) {
                  FocusScopeNode currentFocus = FocusScope.of(context);
    
                  if (!currentFocus.hasPrimaryFocus) {
                    currentFocus.unfocus();
                  }
    
                  Future.delayed(const Duration(milliseconds: 500), () {
                    setState(() {
                      _showPopupMenu(details.globalPosition);
                    });
                  });
                },
                child: (const Icon(Icons.blender_outlined)),
              ),
              PopupMenuButton(
                  itemBuilder: (BuildContext context) => [
                        const PopupMenuItem(child: Text('123')),
                        const PopupMenuItem(child: Text('456'))
                      ])
            ],
          ),
        );
      }
    }
    
    

    so i think there's no better option for it. prefer not using popup and just design the design in a singlechildscrollview