'How to loop the PopupMenuItem in PopupMenuButton in Flutter?

I want to display values from my API in a PopupMenuItem in PopupMenuButton. I manage to display it but I want it to be dynamic. Currently, I hard-coded the index of each item because it seems that I cannot do looping inside PopupMenuButton.

`Widget _simplePopup4() => PopupMenuButton<int>(
    child:  Icon(Icons.arrow_drop_down, color: Colors.orangeAccent),
      offset: Offset(0, 100),
    itemBuilder: (context) => [

      PopupMenuItem(
        value: 1,
        child: Container(
            child: FutureBuilder<SettingCtrl>(
                future: getSettingCtrl(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    if (snapshot.data.setTitle == null) {
                      return Container();
                    } else {
                      return Text(snapshot.data.setTitle[1].title); //index 1
                    }
                  }
                  return CircularProgressIndicator();
                })),
      ),
      PopupMenuDivider(),
      PopupMenuItem(
        value: 1,
        child: Container(
            child: FutureBuilder<SettingCtrl>(
                future: getSettingCtrl(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    if (snapshot.data.setTitle == null) {
                      return Container();
                    } else {
                      return Text(snapshot.data.setTitle[2].title); //index 2
                    }
                  }
                  return CircularProgressIndicator();
                })),
      ),
      PopupMenuDivider(),
      PopupMenuItem(
        value: 1,
        child: Container(
            child: FutureBuilder<SettingCtrl>(
                future: getSettingCtrl(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    if (snapshot.data.setTitle == null) {
                      return Container();
                    } else {
                      return Text(snapshot.data.setTitle[3].title); //index 3
                    }
                  }
                  return CircularProgressIndicator();
                })),
      ),
    ],
  );`

//First attempt which gives error: RenderShrinkWrappingViewport does not support returning intrinsic dimensions.

      Widget _simplePopup5() => PopupMenuButton(
    itemBuilder: (context) {
      var list = List<PopupMenuEntry<Object>>();
      list.add(
        PopupMenuItem(
          value: 1,
          child:  Container(
              child: FutureBuilder<SettingCtrl>(
             
                  future: getSettingCtrl(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      if (snapshot.data.setTitle == null) {
                        return Container();
                      } else {
                        return ListView.builder(
                                physics: NeverScrollableScrollPhysics(),
                                scrollDirection: Axis.vertical,
                                shrinkWrap: true,
                                itemCount: snapshot.data.setTitle.length,
                                itemBuilder:
                                    (BuildContext context, int index) {
                                  return Text(snapshot.data.setTitle[index].title);
                                });
                      }
                    }
                    return CircularProgressIndicator();
                  })),
        ),
      );
      list.add(
        PopupMenuDivider(
          height: 10,
        ),
      );
      return list;
    },
    icon: Icon(
      Icons.settings,
      size: 50,
      color: Colors.white,
    ),
  );

//Second attempt which gives error: Another exception was thrown: A RenderFlex overflowed by 85 pixels on the bottom.

      Widget _simplePopup5() => PopupMenuButton(
    itemBuilder: (context) {
      var list = List<PopupMenuEntry<Object>>();
      list.add(
        PopupMenuItem(
          value: 1,
          child: Container(
              child: FutureBuilder<SettingCtrl>(
                  future: getSettingCtrl(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      final listTitle = <Widget>[];
                      for (var i = 0;
                      i < snapshot.data.setTitle.length;
                      i++) {
                        listTitle.add(SingleChildScrollView(
                            scrollDirection: Axis.vertical,
                            child: InkWell(
                              child:
                              Text(snapshot.data.setTitle[i].title),
                            )));
                      }

                      if (snapshot.data.setTitle == null) {
                        return Container();
                      } else {
                        return Column(children: listTitle);
                      }
                    }
                    return CircularProgressIndicator();
                  })),
        ),
      );
      list.add(
        PopupMenuDivider(
          height: 10,
        ),
      );
      return list;
    },
    icon: Icon(
      Icons.settings,
      size: 50,
      color: Colors.white,
    ),
  );

From the screenshot, only one item are clearly displayed which is "MR" while the other item (before item "MR") are displayed in half. Meanwhile, the rest of the item (after item "MR") being replaced with error message.

The screenshot of the second attempt error

The screenshot of the second attempt error



Solution 1:[1]

The cause of the RenderFlex error is because the child Widget expands beyond the parent Widget. What you can do here is fetch the List of PopupMenu items prior to rendering the PopupMenuButton. With this approach, the List items is ready prior to clicking the PopupMenuButton.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Omatt