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

Flutter如何为展示餐厅列表的SliverList添加固定标题

方案1:标题跟随列表滚动

直接将标题作为列表的第一个子项插入即可,修改后代码如下:

SliverList(
  delegate: SliverChildBuilderDelegate(
    (context, index) {
      // 索引为0时渲染标题
      if (index == 0) {
        return const Padding(
          padding: EdgeInsets.only(left: 15, right: 15, bottom: 10, top: 15),
          child: Text(
            "Top Restaurants",
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
        );
      }
      // 其余索引渲染餐厅卡片,索引需要减1跳过标题占位
      final restaurantIndex = index - 1;
      return Padding(
        padding: const EdgeInsets.only(left: 15.0, right: 15, bottom: 5),
        child: RestaurantWidget(restaurant: _con.topRestaurants[restaurantIndex]),
      );
    },
    // 子项总数为餐厅数量+1个标题
    childCount: _con.topRestaurants.length + 1,
  ),
)

方案2:标题吸顶固定(滚动列表时标题停留在顶部)

在原SliverList上方新增一个SliverPersistentHeader组件,设置pinned: true即可实现吸顶效果,完整代码如下:

CustomScrollView(
  slivers: [
    // 吸顶标题
    SliverPersistentHeader(
      pinned: true,
      delegate: _SliverHeaderDelegate(
        minHeight: 50,
        maxHeight: 50,
        child: Container(
          color: Theme.of(context).scaffoldBackgroundColor,
          padding: const EdgeInsets.symmetric(horizontal: 15),
          alignment: Alignment.centerLeft,
          child: const Text(
            "Top Restaurants",
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
        ),
      ),
    ),
    // 原有餐厅列表,无需修改
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => Padding(
          padding: const EdgeInsets.only(left: 15.0, right: 15, bottom: 5),
          child: RestaurantWidget(restaurant: _con.topRestaurants[index]),
        ),
        childCount: _con.topRestaurants.length,
      ),
    ),
  ],
)

// 自定义SliverHeader代理类
class _SliverHeaderDelegate extends SliverPersistentHeaderDelegate {
  _SliverHeaderDelegate({
    required this.minHeight,
    required this.maxHeight,
    required this.child,
  });

  final double minHeight;
  final double maxHeight;
  final Widget child;

  @override
  double get minExtent => minHeight;
  @override
  double get maxExtent => maxHeight;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(_SliverHeaderDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:45:03