Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle PopupMeniItem presses when using showMenu()

I'm using showMenu() to dispaly popup menu. Usually when you use PopupMenuButton it has the onSelected option, but you don't seem to have it with showMenu().

I tried wrapping the contents of PopupMenuItem inside GestureDetector, but that makes the clickable area just way too small. See picture below, the smaller rectangle is my GestureDetector (which works but is too small) and the bigger rectangle is the inkwell which comes with PopupMenuItem.

GestureDetector inside PopupMenuItem

So my question is, how should I handle PopupMenuItem presses when I don't have the onSelected property?

EDIT:

Here is the code. I have ListTiles, which call this method on LongPress:

void _showOptionsMenu(int hiveIndex) {
    final RenderBox overlay = Overlay.of(context).context.findRenderObject();

showMenu(
  context: context,
  position: RelativeRect.fromRect(
    // magic code from stackoverflow, positions the PopupMenu on your tap location
    _tapPosition & Size(40, 40),
    Offset.zero & overlay.size,
  ),
  items: [
    PopupMenuItem(
      value: 0,
      child: Row(
        children: [
          Icon(Icons.edit),
          Text("Edit"),
        ],
      ),
    ),
    PopupMenuItem(
      value: 1,
      child: Row(
        children: [
          Icon(Icons.delete),
          Text("Delete"),
        ],
      ),
    ),
  ],
);

You can't wrap the PopupMenuItems inside GestureDetector, since the items property only allows PopupMenuItems.

like image 368
steellow Avatar asked Jun 28 '20 16:06

steellow


1 Answers

There is no need to wrap items into gesture detector.. show menu is an async method which returns value of the item menu. When you press any of the item you get back the value of that pressed item. With that value you can do whatever you want. Check this code

 Future<void> _showOptionsMenu(int hiveIndex) async {
    int selected = await showMenu(
      position: RelativeRect.fromLTRB(60.0, 40.0, 100.0, 100.0),
      context: context,
      items: [
        PopupMenuItem(
          value: 0,
          child: Row(
            children: [
              Icon(Icons.edit),
              Text("Edit"),
            ],
          ),
        ),
        PopupMenuItem(
          value: 1,
          child: Row(
            children: [
              Icon(Icons.delete),
              Text("Delete"),
            ],
          ),
        ),
      ],
    );
    if (selected == 0) {
      print('handle edit');
    } else {
      print('handle delete');
    }
  }
like image 165
LonelyWolf Avatar answered Nov 22 '22 06:11

LonelyWolf