Flutter CustomScrollView滚动时SliverPersistentHeader重叠透色问题修复求助
问题场景
- 未滚动时:

- 顶部栏滚动后:

- 底部区域也滚动后:

现有代码
@override Widget build(BuildContext context) { return Scaffold( body: RefreshIndicator( onRefresh: () async => refreshControllers(), child: Stack( children: [ Container(), AssetImageWidget( boxfit: BoxFit.cover, width: MediaQuery.of(context).size.width, imagePath: IconFactory() .getIcon(ref, AppIconsKey.iconDashboardToolBar.name), ), const SizedBox( height: 110, width: double.infinity, child: FittedBox(child: DashboardUserDetailView())), Positioned( top: 110, child: SizedBox( height: MediaQuery.of(context).size.height - 110 - kBottomNavigationBarHeight, width: MediaQuery.of(context).size.width, child: CustomScrollView( slivers: [ const SliverToBoxAdapter( child: NamasteUserView(), ), SliverPersistentHeader( pinned: true, delegate: _SliverHeaderDelegate( minHeight: 52, maxHeight: 52, child: Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(52), topRight: Radius.circular(52), ), ), ), ), ), SliverToBoxAdapter( child: Container( color: Colors.black, height: 100000, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ //Childrens here ], ), ), ), ], ), ), ) ], ), ), ); } class _SliverHeaderDelegate extends SliverPersistentHeaderDelegate { final double minHeight; final double maxHeight; final Widget child; _SliverHeaderDelegate( {required this.minHeight, required this.maxHeight, required this.child}); @override double get minExtent => minHeight; @override double get maxExtent => maxHeight; @override Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { return child; } @override bool shouldRebuild(_SliverHeaderDelegate oldDelegate) { return oldDelegate.minHeight != minHeight || oldDelegate.maxHeight != maxHeight || oldDelegate.child != child; } }
问题描述
我的SliverPersistentHeader是一个带顶部圆角的白色容器,仅圆角区域存在堆叠背景。但滚动时,下方带有指定颜色(因设计约束必须保留该颜色)的容器会因重叠导致圆角区域透出下方颜色,该如何解决?
我希望滚动时,SliverPersistentHeader下方的sliver容器不会透过重叠区域显示自身颜色。
注:因设计约束,必须为sliver容器指定该颜色。
解决方案
方法一:给PersistentHeader容器添加裁剪行为(推荐)
直接在SliverPersistentHeader的容器中添加clipBehavior: Clip.hardEdge,让下方的黑色内容被圆角裁剪,无法透出:
SliverPersistentHeader( pinned: true, delegate: _SliverHeaderDelegate( minHeight: 52, maxHeight: 52, child: Container( clipBehavior: Clip.hardEdge, // 新增裁剪配置 decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(52), topRight: Radius.circular(52), ), ), ), ), ),
方法二:给黑色容器添加顶部遮罩
在黑色容器的顶部添加一个和PersistentHeader圆角完全匹配的白色遮罩,挡住透出的黑色区域:
SliverToBoxAdapter( child: Container( color: Colors.black, height: 100000, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // 新增白色遮罩,高度与PersistentHeader一致 Container( height: 52, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(52), topRight: Radius.circular(52), ), ), ), // 原有子组件放在此处 ], ), ), ),
方法三:利用Delegate的overlapsContent参数动态处理
在_SliverHeaderDelegate的build方法中,根据overlapsContent(是否有内容滚动到Header下方)动态添加裁剪:
@override Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { return overlapsContent ? ClipRRect( borderRadius: const BorderRadius.only( topLeft: Radius.circular(52), topRight: Radius.circular(52), ), child: child, ) : child; }
内容的提问来源于stack exchange,提问作者suprim
相关产品推荐
相关产品推荐

