如何优雅的在Column中嵌入横向滚动的 ListView

example:有一个需求是多个横向滚动的列表纵向排列在一个界面中。

我们直接写,在Column 中直接加上 ListView :

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

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      ListView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: 100,
        itemBuilder: (BuildContext context, int index) {
          return Item();
        },
      ),
    ],);
  }
}

当当当,恭喜你,喜提报错:

在这里插入图片描述

vertical space in which to expand.
解决这个问题,我们通常都会在 ListView 外面添加一个SizedBox 来约束ListView。

SizedBox(
  height: 100.w,
  child: ListView.builder(
    scrollDirection: Axis.horizontal,
    itemCount: 100,
    itemBuilder: (BuildContext context, int index) {
      return Item();
    },
  ),
),

但是! 这这样的写法并不是那么优雅。会在特定情况下出现一出BUG。

当调节手机字体大小的时候,就会导致Item 组件中的字体大小高度发生变化,但是我们约束 ListView 的 SizedBox 的高度是固定的,就会出现溢出报错。

在这里插入图片描述

可能会有人说 可以用 IntrinsicHeight 包裹。但是 ListView 是懒加载的。所以 IntrinsicHeight 不能获取所有的Item的高度。如果Item的高度会变化呢。

itemBuilder: (BuildContext context, int index) {
  if(index > 10){
    return Container(height: 400,width: 200,color: Colors.pink,);
  }
  return Item();
},

上一张图片中,两个同样的ListView 同样的Item。
为什么下面的 ListView 就会根据Item自适应高度。但是上面的就会溢出报错。
这就是今天要讲的优雅的是向 Column 嵌入横向 ListView。
废话不多说直接上代码:

Stack(
  children: [
    const IgnorePointer(
      child: Opacity(
        opacity: 0,
        child: Item(),
      ),
    ),
    const SizedBox(width: double.infinity),
    Positioned.fill(
        child: ListView.builder(
      itemCount: 100,
      scrollDirection: Axis.horizontal,
      itemBuilder: (BuildContext context, int index) {
        return Item();
      },
    )),
  ],
)

解析:
这里用了Stack 的特性。 Stack 的高度会根据 其子组件中 非Positioned组件的最大高度来自撑开的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值