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

保留hasScrollBody:true,限制SliverFillRemaining滚动过度扩展

解决SliverFillRemaining开启hasScrollBody:true时过度扩展的问题

当CustomScrollView中使用SliverFillRemaining且开启hasScrollBody: true时,滚动到底部该组件会过度扩展至整个屏幕,同时需要保留该参数以保证插入新列表元素时滚动位置不变。

解决方案

通过给SliverFillRemaining的子组件添加最大高度约束,限制其高度不超过视口高度,避免过度扩展。以下提供两种实现方式:

方式一:固定视口高度约束

直接通过MediaQuery获取屏幕视口高度,用ConstrainedBox限制子组件最大高度:

CustomScrollView(
  slivers: [
    SliverList(
      delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
          return Card(
            margin: const EdgeInsets.all(15),
            child: Container(
              color: Colors.orange[100 * (index % 12+1)],
              height: 60,
              alignment: Alignment.center,
              child: Text(
                "List Item $index",
                style: const TextStyle(fontSize: 30),
              ),
            ),
          );
        },
        childCount: 10,
      ),
    ),
    SliverFillRemaining(
      hasScrollBody: true,
      fillOverscroll: true,
      child: ConstrainedBox(
        // 限制最大高度为屏幕视口高度
        constraints: BoxConstraints(
          maxHeight: MediaQuery.of(context).size.height,
        ),
        child: Container(
          color: Colors.blue[100],
          child: Icon(
            Icons.sentiment_very_satisfied,
            size: 100,
            color: Colors.blue[900],
          ),
        ),
      ),
    )
  ],
)

方式二:动态获取视口约束

使用SliverLayoutBuilder动态获取当前Sliver的视口约束,适配更复杂的布局场景:

CustomScrollView(
  slivers: [
    SliverList(
      delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
          return Card(
            margin: const EdgeInsets.all(15),
            child: Container(
              color: Colors.orange[100 * (index % 12+1)],
              height: 60,
              alignment: Alignment.center,
              child: Text(
                "List Item $index",
                style: const TextStyle(fontSize: 30),
              ),
            ),
          );
        },
        childCount: 10,
      ),
    ),
    SliverLayoutBuilder(
      builder: (context, constraints) {
        return SliverFillRemaining(
          hasScrollBody: true,
          fillOverscroll: true,
          child: ConstrainedBox(
            // 最大高度限制为当前视口可用高度
            constraints: BoxConstraints(
              maxHeight: constraints.viewportMainAxisExtent,
            ),
            child: Container(
              color: Colors.blue[100],
              child: Icon(
                Icons.sentiment_very_satisfied,
                size: 100,
                color: Colors.blue[900],
              ),
            ),
          ),
        );
      },
    ),
  ],
)

原理说明

添加ConstrainedBox后,SliverFillRemaining的子组件最大高度被限制,即使开启hasScrollBody: true,滚动时也不会过度扩展至整个屏幕;同时保留hasScrollBody: true参数,插入新列表元素时滚动位置不会发生偏移,满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:07:34