How do I open a popup menu from a second widget?
final button = new PopupMenuButton( itemBuilder: (_) => <PopupMenuItem<String>>[ new PopupMenuItem<String>( child: const Text('Doge'), value: 'Doge'), new PopupMenuItem<String>( child: const Text('Lion'), value: 'Lion'), ], onSelected: _doSomething); final tile = new ListTile(title: new Text('Doge or lion?'), trailing: button);
I want to open the button
's menu by tapping on tile
.
Displays a menu when pressed and calls onSelected when the menu is dismissed because an item was selected. The value passed to onSelected is the value of the selected menu item. If we focus on an Application, We can see in every Application there is a Pop Up Menu button that will do some work.
To show a popup menu, use the showMenu function. To create a button that shows a popup menu, consider using PopupMenuButton. To show a checkmark next to a popup menu item, consider using CheckedPopupMenuItem. Typically the child of a PopupMenuItem is a Text widget.
This works, but is inelegant (and has the same display problem as Rainer's solution above:
class _MyHomePageState extends State<MyHomePage> { final GlobalKey _menuKey = GlobalKey(); @override Widget build(BuildContext context) { final button = PopupMenuButton( key: _menuKey, itemBuilder: (_) => const<PopupMenuItem<String>>[ PopupMenuItem<String>( child: Text('Doge'), value: 'Doge'), PopupMenuItem<String>( child: Text('Lion'), value: 'Lion'), ], onSelected: (_) {}); final tile = ListTile(title: Text('Doge or lion?'), trailing: button, onTap: () { // This is a hack because _PopupMenuButtonState is private. dynamic state = _menuKey.currentState; state.showButtonMenu(); }); return Scaffold( body: Center( child: tile, ), ); } }
I suspect what you're actually asking for is something like what is tracked by https://github.com/flutter/flutter/issues/254 or https://github.com/flutter/flutter/issues/8277 -- the ability to associated a label with a control and have the label be clickable -- and is a missing feature from the Flutter framework.
I think it would be better do it in this way, rather than showing a PopupMenuButton
void _showPopupMenu() async { await showMenu( context: context, position: RelativeRect.fromLTRB(100, 100, 100, 100), items: [ PopupMenuItem<String>( child: const Text('Doge'), value: 'Doge'), PopupMenuItem<String>( child: const Text('Lion'), value: 'Lion'), ], elevation: 8.0, ); }
There will be times when you would want to display _showPopupMenu at the location where you pressed on the button Use GestureDetector for that
final tile = new ListTile( title: new Text('Doge or lion?'), trailing: 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, ); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With