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

Flutter中如何让ListView子项占满固定高度Container的全部空间

解决Flutter中ListView.separated子项均分固定高度容器空间的问题

问题根源

ListView.separated 默认是可滚动组件,它会根据子项自身高度布局,不会主动填充父容器剩余空间——哪怕用Expanded包裹ListView,也只是让ListView占满父容器,但子项依然不会自动均分高度。


方案一:用Column替代ListView.separated(推荐,无需计算高度)

你的容器高度固定(300)、子项数量固定(7个),且不需要滚动功能,直接用Column结合分隔符更简单,每个子项用Expanded包裹即可自动均分空间:

修改后的DailyWeatherListCardWidget代码:

class DailyWeatherListCardWidget extends StatelessWidget {
  const DailyWeatherListCardWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 300,
      alignment: Alignment.center,
      padding: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        color: const Color.fromRGBO(112, 176, 250, 1),
        borderRadius: BorderRadius.circular(20),
      ),
      child: Column(
        children: List.generate(7, (index) {
          return Column(
            children: [
              Expanded(child: DailyWeatherCardWidget()),
              if (index != 6) const Divider(), // 最后一个子项后不加分隔符
            ],
          );
        }),
      ),
    );
  }
}

同时调整DailyWeatherCardWidget,确保子项能填充Expanded的空间:

class DailyWeatherCardWidget extends StatelessWidget {
  const DailyWeatherCardWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: const [
          Expanded(
            child: Padding(
              padding: EdgeInsets.only(left: 12.0),
              child: Text("Day"),
            ),
          ),
          Icon(Icons.water_drop, size: 18),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Text("50%"),
          ),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Icon(Icons.sunny, size: 18),
          ),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Icon(Icons.cloud, size: 18),
          ),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Text("29° 20°"),
          ),
        ],
      ),
    );
  }
}

方案二:继续使用ListView.separated(需手动计算高度)

如果必须保留ListView.separated,需要禁用滚动并手动计算子项高度:

  1. 计算总可用高度:容器高度300减去上下padding(8×2=16),得到284;
  2. 7个子项对应6个分隔符,默认Divider高度为1,总分隔符高度为6×1=6;
  3. 单个子项高度 = (284 - 6) ÷7 ≈39.7,取整为39或40。

修改后的DailyWeatherListCardWidget代码:

class DailyWeatherListCardWidget extends StatelessWidget {
  const DailyWeatherListCardWidget({super.key});

  @override
  Widget build(BuildContext context) {
    final itemHeight = (300 - 16 - 6) /7;
    return Container(
      width: double.infinity,
      height: 300,
      alignment: Alignment.center,
      padding: const EdgeInsets.all(8.0),
      decoration: BoxDecoration(
        color: const Color.fromRGBO(112, 176, 250, 1),
        borderRadius: BorderRadius.circular(20),
      ),
      child: ListView.separated(
        shrinkWrap: true,
        physics: const NeverScrollableScrollPhysics(),
        separatorBuilder: ((context, index) => const Divider()),
        itemCount: 7,
        itemBuilder: (context, index) {
          return SizedBox(
            height: itemHeight,
            child: DailyWeatherCardWidget(),
          );
        },
      ),
    );
  }
}

调整DailyWeatherCardWidget让内容居中:

class DailyWeatherCardWidget extends StatelessWidget {
  const DailyWeatherCardWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return SizedBox.expand(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: const [
          Expanded(
            child: Padding(
              padding: EdgeInsets.only(left: 12.0),
              child: Text("Day"),
            ),
          ),
          Icon(Icons.water_drop, size: 18),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Text("50%"),
          ),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Icon(Icons.sunny, size: 18),
          ),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Icon(Icons.cloud, size: 18),
          ),
          Padding(
            padding: EdgeInsets.only(right: 12.0),
            child: Text("29° 20°"),
          ),
        ],
      ),
    );
  }
}

总结

  • 无需滚动场景优先用Column + Expanded方案,无需手动计算高度,适配性更强;
  • 必须用ListView.separated时,需禁用滚动、开启shrinkWrap,并手动计算子项高度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:21:38