flutter - How to show icon and text on PopupMenuButton items

Flutter - PopupMenuButton Icon & Text
The PopupMenuButton class allows us to display 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. The flutter developers can provide one of a child or an icon but not both. If developers provide an icon then PopupMenuButton behaves like an IconButton. If both child and icon are null, then a standard overflow icon is created depending on the platform.

The following flutter app development tutorial will demonstrate how to display both a text and an icon on each item in a PopupMenuButton widget. Here we used the PopupMenuButton class’s itemBuilder property to add items to the PupupMenuButton widgets. And also configure the menu items to show text and an icon inside each item of the PopupMenuButton widget.

The PopupMenuButton class’s itemBuilder property value is a PopupMenuItemBuilder instance. The PopupMenuItemBuilder is called when the button is pressed to create the items to show in the menu. The PopupMenuItemBuilder is used by PopupMenuButton to lazily construct the items shown when the button is pressed.

The flutter PopupMenuItem class represents an item in a material design popup menu. Normally the child of a PopupMenuItem is a Text widget. But in this flutter tutorial, we will display both a text and an icon on each item of the PopupMenuButton widget.

The PopupMenuItem class’s child property value is a widget that is widget below this widget in the tree. We will put a Row widget for this child property value. Then we will put an Icon widget and a Text widget in the Row widget. So our menu item will show a text and an icon inside the item. These are the simple steps to display both a text and an icon on PopupMenuButton items. We used a SizedBox to add padding between the text and the icon. Here we also wrap the PopupMenuButton widget by a Theme.

So finally, the flutter app developers can display text and an icon inside the item of a PopupMenuButton widget while creating the item. They should put a Row widget as a child of the item. And they also have to put a Text widget and an Icon widget inside the Row widget.
main.dart

import 'package:flutter/material.dart';

void main() {runApp(const MyApp());}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData(primarySwatch: Colors.indigo),
        home: const MyHomePage()
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: const Text("PopupMenuButton Icon & Text"),
            actions: [
              Theme(
                  data: Theme.of(context).copyWith(
                      iconTheme: const IconThemeData(
                          color: Colors.black87
                      )
                  ),
                  child: PopupMenuButton<int>(
                      offset: const Offset(0, 56),
                      itemBuilder: (context) => [
                        PopupMenuItem<int>(
                            child: Row(
                                children: const [
                                  Icon(Icons.share_location),
                                  SizedBox(width: 8),
                                  Text("Share Location")
                                ]
                            )
                        ),
                        PopupMenuItem<int>(
                            child: Row(
                                children: const [
                                  Icon(Icons.upload_file),
                                  SizedBox(width: 8),
                                  Text("Upload File")
                                ]
                            )
                        ),
                        PopupMenuItem<int>(
                            child: Row(
                                children: const [
                                  Icon(Icons.email),
                                  SizedBox(width: 8),
                                  Text("Mail Us")
                                ]
                            )
                        )
                      ]
                  )
              )
            ]
        )
    );
  }
}