如何在Flutter中为SliverList添加渐隐边缘效果
给Flutter的SliverList添加渐隐边缘效果
要实现SliverList的上下边缘渐隐效果,你可以自定义一个SliverShaderMask组件,通过Shader遮罩实现渐变透明效果,既保留Sliver的滚动特性,又能精准控制渐隐区域。
步骤1:实现自定义SliverShaderMask
这个组件可以将Shader遮罩应用到子Sliver上:
class SliverShaderMask extends SingleChildRenderObjectWidget { const SliverShaderMask({ super.key, required this.shaderCallback, super.child, }); final ShaderCallback shaderCallback; @override RenderObject createRenderObject(BuildContext context) { return _RenderSliverShaderMask()..shaderCallback = shaderCallback; } @override void updateRenderObject(BuildContext context, _RenderSliverShaderMask renderObject) { renderObject.shaderCallback = shaderCallback; } } class _RenderSliverShaderMask extends RenderProxySliver { ShaderCallback? shaderCallback; @override void paint(PaintingContext context, Offset offset) { if (shaderCallback == null) { super.paint(context, offset); return; } final bounds = offset & child!.geometry!.paintBounds; final shader = shaderCallback!(bounds); context.pushLayer( ShaderMaskLayer(shader: shader), (context, offset) => super.paint(context, offset), offset, ); } }
步骤2:将SliverList包裹在SliverShaderMask中
修改原有代码,用SliverShaderMask包裹SliverList所在的SliverPadding,通过LinearGradient定义渐隐区域:
class MyWidget extends StatefulWidget { const MyWidget({Key? key}) : super(key: key); @override State<MyWidget> createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF4c4452), body: CustomScrollView(slivers: <Widget>[ // SliverAppBar部分保留不变 SliverAppBar( backgroundColor: const Color(0xff4c4452), elevation: 0, automaticallyImplyLeading: false, expandedHeight: 300, pinned: true, bottom: PreferredSize( preferredSize: const Size.fromHeight(70), child: Container( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text("Some Title", style: TextStyle( color: Colors.white, fontSize: 25, fontFamily: 'OpenSans', fontWeight: FontWeight.w600)), ], ), ), ), ), // 用SliverShaderMask包裹SliverList SliverShaderMask( shaderCallback: (bounds) => LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, // 定义渐变:上下边缘透明,中间完全显示 colors: [ Colors.transparent, Colors.white, Colors.white, Colors.transparent, ], // 控制渐隐区域范围,上下各5%区域为渐隐效果 stops: const [0.0, 0.05, 0.95, 1.0], ).createShader(bounds), child: SliverPadding( padding: const EdgeInsets.symmetric(vertical: 20), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index) { return Container( child: Text("Some thing to test with something to test with", style: TextStyle(color: Colors.white)), ); }, childCount: 20), ), ), ), ]), ); } }
效果说明
- 调整
stops参数可以改变渐隐区域大小,比如将0.05改为0.1,渐隐区域会扩大到上下各10%。 - 若需调整渐隐颜色过渡,修改
colors数组即可,注意要与文本颜色或页面背景色匹配。
内容的提问来源于stack exchange,提问作者daniel
相关产品推荐
相关产品推荐

