Home > Mobile >  Flutter bug with PopupMenuButton and TextFiend inside AlertDialog
Flutter bug with PopupMenuButton and TextFiend inside AlertDialog

Time:01-25

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.stack.imgur.com/dNjq1.gif

CodePudding user response:

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

CodePudding user response:

Please update your code with this :

You have to give child: widget to open the PopupMenuButton

return AlertDialog(
  content: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      TextField(),
      PopupMenuButton(
        offset: /// here your solution
        child: const Text("click here"),
        itemBuilder: (BuildContext context) => [
              const PopupMenuItem(child: Text('123')),
              const PopupMenuItem(child: Text('456'))
            ]),
    ],
  ),
);
  • Related