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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:06:29