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

Flutter ListView不遵守容器约束,超出显示问题求助

问题:ListView无法遵守容器高度约束,且ListTile背景异常显示

我尝试让ListView仅占据屏幕60%的高度,但它始终延伸至屏幕底部,不受外层SizedBox的约束。同时,容器外的ListTile即使没有内部组件,白色背景依然会显示出来。

相关代码

@override
Widget build(BuildContext context) {
  return FutureBuilder(
      future: pedidos,
      builder: (context, AsyncSnapshot<List<Pedido>> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              SizedBox(
                height: MediaQuery.of(context).size.height * 0.6,
                child: ListView.builder(
                    itemCount: snapshot.data!.length,
                    shrinkWrap: true,
                    itemBuilder: (context, index) {
                      return Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Hero(
                            tag:
                                "pedidos_card${snapshot.data![index].idPedido}",
                            child: ListTile(
                              tileColor: Colors.white,
                              leading: Container(
                                width: 50,
                                height: 50,
                                decoration: BoxDecoration(
                                    color: Colors.blue,
                                    shape: BoxShape.circle),
                                child: Center(
                                  child: Text(
                                      style: Theme.of(context)
                                          .textTheme
                                          .headlineSmall,
                                      "${snapshot.data![index].idPedido}"),
                                ),
                              ),
                              title: Text(
                                  'Pedido: ${snapshot.data![index].idPedido}'),
                              subtitle: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  SizedBox(height: 10),
                                  Text(
                                      'Estado: ${snapshot.data![index].estadoPedido.last.tipoEstadoPedido.name}'),
                                  SizedBox(height: 10),
                                  Text(
                                      "Cliente: ${snapshot.data![index].cliente.nombre}")
                                ],
                              ),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(10),
                              ),
                              trailing: Checkbox(
                                value: pedidosSeleccion
                                    .contains(snapshot.data![index]),
                                onChanged: (bool? value) {
                                  // value = checkboxList[index];
                                  // setState(() {});
                                },
                              ),
                              onTap: () {
                                bool isSelected = pedidosSeleccion
                                    .contains(snapshot.data![index]);
                                if (isSelected) {
                                  pedidosSeleccion
                                      .remove(snapshot.data![index]);
                                } else {
                                  pedidosSeleccion.add(snapshot.data![index]);
                                }

                                setState(() {});
                              },
                            ),
                          ));
                    }),
              ),
              ElevatedButton(
                  onPressed: () {}, child: Text('Ver ultima milla')),
            ],
          );
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      });
}

问题示例截图

ListView高度溢出及背景异常


解决方法

1. 修复ListView高度约束问题

你给ListView设置了shrinkWrap: true,这个属性会让ListView根据子项总高度自适应,直接忽略外层SizedBox的高度限制。只需移除shrinkWrap: true,ListView就会遵守SizedBox的高度约束,超出可视区域的内容可通过滚动查看。

修改后的ListView代码片段:

ListView.builder(
    itemCount: snapshot.data!.length,
    // 移除shrinkWrap: true
    itemBuilder: (context, index) {
        // 原有子项代码保持不变
    },
)

2. 解决ListTile背景溢出问题

ListTile的tileColor会填充整个组件区域,滚动时超出可视范围的背景依然会被绘制。可以通过以下两种方式修复:

  • 用ClipRRect包裹ListTile,配合圆角裁剪多余背景:
Padding(
    padding: const EdgeInsets.all(8.0),
    child: Hero(
        tag: "pedidos_card${snapshot.data![index].idPedido}",
        child: ClipRRect(
            borderRadius: BorderRadius.circular(10),
            child: ListTile(
                tileColor: Colors.white,
                // 原有ListTile属性保持不变
            ),
        ),
    ),
)
  • 或者用外层Container设置背景,移除ListTile的tileColor:
Padding(
    padding: const EdgeInsets.all(8.0),
    child: Container(
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(10),
        ),
        child: Hero(
            tag: "pedidos_card${snapshot.data![index].idPedido}",
            child: ListTile(
                // 移除tileColor属性
                // 原有ListTile属性保持不变
            ),
        ),
    ),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 03:36:20