Flutter笔记--SliverFloatingHeader

        Flutter开发中,SliverFloatingHeader是专门用于简化浮动头部的实现,它的作用是响应用户的滚动方向来控制头部组件的显示与隐藏,简单总结如下:

API:
FloatingHeaderSnapMode.overlay:当向下滑动触发头部展开时,头部会像浮层一样直接覆盖在列表内容的上方。
FloatingHeaderSnapMode.scroll:适合不需要改变列表滚动位置的悬浮组件。例如,应用首页的搜索栏或悬浮操作按钮。
场景:
1 应用首页搜索栏
2 新闻应用标题栏
栗子:

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("浮动卡片区域")),
        body: CustomScrollView(
          slivers: [
            SliverFloatingHeader(
              animationStyle: AnimationStyle(
                duration: const Duration(milliseconds: 220),
                curve: Curves.easeOut,
              ),
              snapMode: FloatingHeaderSnapMode.overlay,
              child: Container(
                margin: const EdgeInsets.all(12),
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: Colors.blueAccent.shade100,
                  borderRadius: BorderRadius.circular(10),
                ),
                child: const Text(
                  "浮动展示卡片:拖动滚动会触发吸附动画",
                  style: TextStyle(fontSize: 16),
                ),
              ),
            ),
            SliverList(
              delegate: SliverChildBuilderDelegate(
                    (context, index) => ListTile(
                  leading: const Icon(Icons.inventory_2),
                  title: Text("商品条目 ${index + 1}"),
                  subtitle: Text("条目详情描述 ${index + 1}"),
                ),
                childCount: 35,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
class StickyHeaderDelegate extends SliverPersistentHeaderDelegate {
  final Widget content;
  final double height;
  StickyHeaderDelegate({required this.content, required this.height});

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) => content;

  @override
  double get maxExtent => height;

  @override
  double get minExtent => height;

  @override
  bool shouldRebuild(covariant StickyHeaderDelegate oldDelegate) => oldDelegate.content != content;
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("多模块滚动布局")),
        body: CustomScrollView(
          slivers: [
            SliverToBoxAdapter(
              child: Container(
                height: 130,
                width: double.infinity,
                color: Colors.orangeAccent,
                alignment: Alignment.center,
                child: const Text("首页活动横幅", style: TextStyle(fontSize: 22, color: Colors.white)),
              ),
            ),
            // 浮动公告卡片
            SliverFloatingHeader(
              animationStyle: AnimationStyle(
                duration: const Duration(milliseconds: 280),
                curve: Curves.easeInOutCubic,
              ),
              snapMode: FloatingHeaderSnapMode.scroll,
              child: Container(
                margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                padding: const EdgeInsets.all(14),
                decoration: BoxDecoration(
                  color: Colors.indigo.shade50,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: const Text("限时公告:全场数码商品满减活动开启"),
              ),
            ),
            // 第一层常驻吸顶栏
            SliverPersistentHeader(
              pinned: true,
              delegate: StickyHeaderDelegate(
                height: 46,
                content: Container(
                  color: Colors.teal,
                  alignment: Alignment.centerLeft,
                  padding: const EdgeInsets.only(left: 16),
                  child: const Text("一级分类:数码专区", style: TextStyle(color: Colors.white)),
                ),
              ),
            ),
            SliverPersistentHeader(
              pinned: true,
              delegate: StickyHeaderDelegate(
                height: 42,
                content: Container(
                  color: Colors.green.shade400,
                  alignment: Alignment.centerLeft,
                  padding: const EdgeInsets.only(left: 16),
                  child: const Text("二级分类:手机配件", style: TextStyle(color: Colors.white)),
                ),
              ),
            ),

            SliverList(
              delegate: SliverChildBuilderDelegate(
                    (context, index) => ListTile(
                  title: Text("数码单品 ${index + 1}"),
                  trailing: Text("¥${99 + index * 20}"),
                ),
                childCount: 50,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

注意:
1 必须配合CustomScrollView
2 避免嵌套滚动视图 确保所有的Sliver组件都在同一个CustomScrollView中,避免嵌套多个滚动视图导致滚动冲突问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值