I believe that in the actual development process, certainly not such a function:

Click the button in the upper right corner of the AppBar to pop up a menu for the user to choose from.

Fortunately, Flutter provides us with a Widget that directly achieves this effect.

PopupMenuButton

As usual, here’s the official note:

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.

One of child or icon may be provided, but not both. If icon is provided, then PopupMenuButton behaves like an IconButton.

If both are null, then a standard overflow icon is created (depending on the platform).

Roughly meaning:

A menu is displayed when pressed, and onSelected is called when an item is selected, passing the value of the selected menu.

You can provide a child or icon, but not both.

If empty, a default icon is provided, depending on the platform.

The constructor

Having read the official description, let’s look at the constructor:

const PopupMenuButton({
  Key key,
  @required this.itemBuilder,
  this.initialValue,
  this.onSelected,
  this.onCanceled,
  this.tooltip,
  this.elevation = 8.0.this.padding = const EdgeInsets.all(8.0),
  this.child,
  this.icon,
  this.offset = Offset.zero,
  this.enabled = true,}) :assert(itemBuilder ! =null),
assert(offset ! =null),
assert(enabled ! =null),
assert(! (child ! =null&& icon ! =null)), // fails if passed both parameters
super(key: key);
Copy the code

And each of these parameters should be pretty straightforward, so I’m not going to explain it too much,

The only required argument is the itemBuilder. You can also see the following assertion:

assert(! (child ! = null && icon ! = null)) check if both child and icon are not null.

A simple Demo

The constructor is now available in a Demo. Let’s see how it works:

Look at the code again:

/// first we define an enumeration
enum WhyFarther {
  harder,
  smarter,
  selfStarter,
  tradingCharter,
}

/// ------------------------------------

/ / / the build method
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('PopupMenuButtonPage'),
      actions: <Widget>[
        PopupMenuButton<WhyFarther>(
          onSelected: (WhyFarther result) {
            setState(() {
              _selection = result;
            });
          },
          icon: Icon(Icons.more_vert),
          itemBuilder: (BuildContext context) => <PopupMenuEntry<WhyFarther>>[
            const PopupMenuItem<WhyFarther>(
              value: WhyFarther.harder,
              child: Text('Working a lot harder'),),const PopupMenuItem<WhyFarther>(
              value: WhyFarther.smarter,
              child: Text('Being a lot smarter'),),const PopupMenuItem<WhyFarther>(
              value: WhyFarther.selfStarter,
              child: Text('Being a self-starter'),),const PopupMenuItem<WhyFarther>(
              value: WhyFarther.tradingCharter,
              child: Text('Placed in charge of trading charter'),
            ),
          ],
        ),
      ],
    ),
    body: Container(),
  );
}
Copy the code

To explain the logic:

  1. We first define an enumeration
  2. Then, inAppBar“Actions” is definedPopupMenuButton
  3. Set the icon forIcon(Icons.more_vert)
  4. itemBuilderNeed to return oneList<PopupMenuEntry<T>>
  5. The value that’s passed in here isPopupMenuItem<WhyFarther>
  6. And then define theonSelectedParameter receive click callback

So the overall logic is defined, let’s run it:

conclusion

The result is a super simple and useful menu popup,

The implementation logic is similar to that of DropdownButton using PopupRoute,

If you are interested in this topic, you can check out my previous article on Flutter source series: DropdownButton source code

The full code has been uploaded to GitHub: github.com/wanglu1209/…