【问题标题】:How to loop the PopupMenuItem in PopupMenuButton in Flutter?如何在 Flutter 中循环 PopupMenuButton 中的 PopupMenuItem?
【发布时间】:2019-08-30 02:13:27
【问题描述】:

我想在 PopupMenuButton 的 PopupMenuItem 中显示来自我的 API 的值。我设法显示它,但我希望它是动态的。目前,我对每个项目的索引进行了硬编码,因为我似乎无法在 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();
                })),
      ),
    ],
  );`

//第一次尝试报错:RenderShrinkWrappingViewport 不支持返回固有尺寸。

      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,
    ),
  );

//第二次尝试报错:抛出了另一个异常:A RenderFlex 在底部溢出了 85 个像素。

      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,
    ),
  );

从截图中,只有一个项目清晰显示,即“MR”,而另一个项目(在项目“MR”之前)显示为一半。同时,项目的其余部分(在项目“MR”之后)被替换为错误消息。

第二次尝试错误截图

【问题讨论】:

  • 你所说的'是什么意思。我设法显示它,但我希望它是动态的'?会有多动态?如果它的弹出选项在屏幕开始时更改一次,我可以提供帮助。但是如果每个弹出按钮点击它都会刷新,我不能这样做
  • 嗨@ejabu!实际上,我的意思是,如何循环弹出菜单项,因为我首先对索引进行了硬编码。然后,当我尝试第二次尝试(在弹出菜单项内循环)时,它只清楚地显示一项并给出错误底部溢出某些像素(可以参考屏幕截图)。

标签: flutter flutter-layout


【解决方案1】:

RenderFlex 错误的原因是子 Widget 扩展超出了父 Widget。您可以在这里做的是在呈现PopupMenuButton 之前获取PopupMenu 项目列表。使用这种方法,列表项在单击PopupMenuButton 之前就已准备就绪。

【讨论】:

    猜你喜欢
    • 2018-09-07
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    相关资源
    最近更新 更多