如何隐藏被其他组件遮挡的SliverAppBar部分内容?
解决 Netflix 风格 AppBar 文本遮挡裁剪问题
要实现文本被第一个固定 AppBar 遮挡部分消失的效果,我们需要通过自定义裁剪器结合滚动偏移量来动态裁剪文本内容。以下是修改后的完整代码:
import 'package:flutter/material.dart'; class TopClip extends CustomClipper<Rect> { final double clipAmount; TopClip(this.clipAmount); @override Rect getClip(Size size) { // 裁剪顶部指定高度的区域 return Rect.fromLTWH(0, clipAmount, size.width, size.height - clipAmount); } @override bool shouldReclip(covariant TopClip oldClipper) { return oldClipper.clipAmount != clipAmount; } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { double scrollOffset = 0.0; // 根据滚动偏移计算透明度,上限0.4 double get opacity => scrollOffset / 100 > 0.4 ? 0.4 : scrollOffset / 100; @override Widget build(BuildContext context) { // 计算裁剪高度:滚动偏移超过40时开始裁剪,最大裁剪高度为文本近似高度20 double clipAmount = scrollOffset > 40 ? scrollOffset - 40 : 0; clipAmount = clipAmount > 20 ? 20 : clipAmount; return Scaffold( backgroundColor: Colors.purple.shade100, body: SafeArea( child: Stack( children: [ NotificationListener<ScrollUpdateNotification>( onNotification: (notification) { setState(() { scrollOffset = notification.metrics.pixels; }); return true; }, child: CustomScrollView( slivers: [ SliverAppBar( expandedHeight: 0, pinned: true, backgroundColor: Colors.black.withOpacity(opacity), shadowColor: Colors.transparent, title: const Text( 'Stacked Container', style: TextStyle( color: Colors.white, fontSize: 22.0, fontWeight: FontWeight.bold, ), ), toolbarHeight: 60, ), SliverAppBar( clipBehavior: Clip.none, floating: true, toolbarHeight: 25, shadowColor: Colors.transparent, backgroundColor: Colors.transparent, bottom: PreferredSize( preferredSize: const Size(double.infinity, 10), child: ClipRect( clipper: TopClip(clipAmount), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox(width: 15.0), Opacity( opacity: 1 - opacity, child: const Text( 'Sliver AppBar', style: TextStyle( fontSize: 20.0, color: Colors.green, ), ), ), const SizedBox(width: 15.0), ], ), ), ), ), SliverList( delegate: SliverChildListDelegate( [ ListView.builder( itemCount: 10, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return Container( margin: const EdgeInsets.fromLTRB(10.0, 20, 10, 10), color: Colors.deepPurple, height: 300, width: double.infinity, ); }, ) ], ), ) ], ), ), ], ), ), ); } }
关键修改说明:
- 自定义裁剪器
TopClip:根据传入的裁剪高度,裁剪文本顶部的指定区域,实现被遮挡部分消失的效果。 - 滚动偏移跟踪:使用
scrollOffset变量记录滚动位置,替代原有的单一透明度变量,同时用于计算裁剪高度。 - 动态裁剪计算:当滚动偏移超过40时开始裁剪文本,最大裁剪高度设为文本近似高度20,确保文本完全被遮挡时不再显示。
- ClipRect 包裹文本:将第二个 SliverAppBar 的文本内容用
ClipRect包裹,应用自定义裁剪器实现动态裁剪。
内容的提问来源于stack exchange,提问作者Kartik
相关产品推荐
相关产品推荐

