How dynamically create and show a popup menu in flutter?
Yes it is possible
void _showPopupMenu() async { await showMenu( context: context, position: RelativeRect.fromLTRB(100, 100, 100, 100), items: [ PopupMenuItem( value: 1 child: Text("View"), ), PopupMenuItem( value: 2 child: Text("Edit"), ), PopupMenuItem( value: 3 child: Text("Delete"), ), ], elevation: 8.0, ).then((value){// NOTE: even you didnt select item this method will be called with null of value so you should call your call back with checking if value is not null if(value!=null) print(value); }); }
There will be times when you would want to display _showPopupMenu at the location where you pressed on the buttonUse GestureDetector for that
GestureDetector( onTapDown: (TapDownDetails details) { _showPopupMenu(details.globalPosition); }, child: Container(child: Text("Press Me")),);
and then _showPopupMenu will be like
_showPopupMenu(Offset offset) async { double left = offset.dx; double top = offset.dy; await showMenu( context: context, position: RelativeRect.fromLTRB(left, top, 0, 0), items: [ ..., elevation: 8.0, );}
@Vishal Singh answer was really helpful. However, I had the problem that the menu was always on the right. Giving the right value a really high value fixed it,Example:
_showPopupMenu(Offset position) async { await showMenu( context: context, position: RelativeRect.fromLTRB(position.dx, position.dy, 100000, 0), ...
@Vishal Singh's answer needs two improvements:
- If you use
0
forright
, then the menu is aligned to the right because
Horizontally, the menu is positioned so that it grows in the direction that has the most room. For example, if the position describes a rectangle on the left edge of the screen, then the left edge of the menu is aligned with the left edge of the position, and the menu grows to the right.
- If you use
0
forbottom
, this works fine with a popup menu withoutinitialValue
but moves the menu far down ifinitialValue
is set. This is because
If initialValue is specified then the first item with a matching value will be highlighted and the value of position gives the rectangle whose vertical center will be aligned with the vertical center of the highlighted item (when possible).
If initialValue is not specified then the top of the menu will be aligned with the top of the position rectangle.
https://api.flutter.dev/flutter/material/showMenu.html
So for a more universal solution calculate the right and the bottom correctly:
final screenSize = MediaQuery.of(context).size; showMenu( context: context, position: RelativeRect.fromLTRB( offset.dx, offset.dy, screenSize.width - offset.dx, screenSize.height - offset.dy, ), items: [ // ... ], );