You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何构建内置可滚动ElevatedButton列表的自定义Row组件

报错原因

  • 第一类Horizontal viewport was given unbounded width是因为横向滚动的ListView外层没有明确的宽度约束,Row的子元素默认会尽可能占满水平空间,横向列表没有边界就触发布局溢出。
  • 第二类RenderBox was not laid out是因为你在横向ListView的子元素里加了Expanded,滚动列表的子元素在滚动方向上没有上限,Expanded无法计算可占用的空间,导致布局无法生成尺寸。

修复步骤

  1. 把原来包裹横向ListView的无尺寸SizedBox替换为Expanded,让横向按钮区域占用Row内TextField和删除按钮之外的剩余可用宽度,获得明确的宽度约束。
  2. 删除横向ListView内部所有ElevatedButton外层的Expanded,按钮会自动适配自身内容宽度,不会触发布局计算冲突。
  3. 如果需要限制横向按钮区域的最大宽度,可以在Expanded内部嵌套ConstrainedBox设置maxWidth参数即可。

修复后核心代码示例

if(widget == "selection"){
  return Row(
    children: [
      Expanded(
        child: TextField(
          onChanged: (val){
            onUpdate(key, val);
          },
          keyboardType: type,
          decoration: InputDecoration(
            labelText: key.toString(),
            labelStyle: TextStyle(
              fontSize: 14.0,
            ),
            hintStyle: TextStyle(
              color: Colors.grey,
              fontSize: 10.0,
            ),
          ),
          style: TextStyle(fontSize: 14.0),
        ),
      ),
      SizedBox(width: 8.0,),
      // 替换原有SizedBox为Expanded提供宽度约束
      Expanded(
        // 可选:添加ConstrainedBox限制最大宽度
        // child: ConstrainedBox(
        //   constraints: BoxConstraints(maxWidth: 250),
          child: ListView(
            scrollDirection: Axis.horizontal,
            children: [
              // 移除所有按钮外层的Expanded
              ElevatedButton(
                onPressed: (){},
                child: Text("HELLO"),
              ),
              SizedBox(width: 4),
              ElevatedButton(
                onPressed: (){},
                child: Text("HELLO"),
              ),
              SizedBox(width: 4),
              ElevatedButton(
                onPressed: (){},
                child: Text("HELLO"),
              ),
              SizedBox(width: 4),
              // 新增按钮入口
              TextButton(
                onPressed: (){
                  // 在这里实现新增按钮的逻辑,把按钮项存入对应状态列表动态渲染即可
                },
                child: Icon(Icons.add),
              )
            ],
          ),
        // ),
      ),
      SizedBox(width: 4.0,),
      TextButton(
        onPressed: (){
          setState(() {
            Map<String, dynamic> tempMap = {};
            for(final element in widgetList) {
              if(element["id"] == key){
                tempMap = element;
                break;
              }
            }
            widgetList.remove(tempMap);

            for(final element in customTextValuesList) {
              if(element["id"] == key){
                tempMap = element;
                break;
              }
            }

            customTextValuesList.remove(tempMap);
          });

        },
        child: Icon(Icons.close, color: Colors.red,),
      ),
    ],
  );
}

动态新增按钮可以通过状态管理实现:把每个selection类型行的按钮列表存在和行key绑定的数组中,动态遍历数组渲染按钮,点击+按钮时给对应数组新增一项即可。

内容的提问来源于stack exchange,提问作者Firenze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 17:45:04