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

如何为Flutter Widget四边添加渐变颜色遮罩效果?

实现四边渐变遮罩的Flutter Widget

要实现四边(上、下、左、右)都带有边缘向中心过渡的渐变遮罩,你可以通过**嵌套ShaderMask**的方式,分别处理水平和垂直方向的渐变,再叠加效果。以下是具体实现方案:

基础四边渐变遮罩

直接嵌套两个ShaderMask,分别实现左右和上下方向的渐变遮罩,结合BlendMode.dstIn让遮罩以透明度裁剪子Widget,避免颜色覆盖:

ShaderMask(
  // 左右方向渐变遮罩
  shaderCallback: (Rect rect) {
    return const LinearGradient(
      begin: Alignment.centerLeft,
      end: Alignment.centerRight,
      colors: [Colors.white, Colors.transparent, Colors.transparent, Colors.white],
      stops: [0.0, 0.03, 0.99, 1.0], // 边缘3%范围从白色过渡到透明
    ).createShader(rect);
  },
  blendMode: BlendMode.dstIn, // 用遮罩透明度裁剪子Widget
  child: ShaderMask(
    // 上下方向渐变遮罩
    shaderCallback: (Rect rect) {
      return const LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: [Colors.white, Colors.transparent, Colors.transparent, Colors.white],
        stops: [0.0, 0.03, 0.99, 1.0],
      ).createShader(rect);
    },
    blendMode: BlendMode.dstIn,
    child: YourChildWidget(), // 替换为你需要添加遮罩的子Widget
  ),
)

滚动过渡效果优化

如果需要像Spotify那样随滚动动态调整遮罩范围,可以结合ScrollController监听滚动偏移,动态修改渐变的stops参数:

class FourEdgeGradientMask extends StatefulWidget {
  final Widget child;
  final ScrollController scrollController;

  const FourEdgeGradientMask({
    super.key,
    required this.child,
    required this.scrollController,
  });

  @override
  State<FourEdgeGradientMask> createState() => _FourEdgeGradientMaskState();
}

class _FourEdgeGradientMaskState extends State<FourEdgeGradientMask> {
  double _scrollOffset = 0.0;

  @override
  void initState() {
    super.initState();
    widget.scrollController.addListener(_onScroll);
    _scrollOffset = widget.scrollController.offset;
  }

  void _onScroll() {
    setState(() {
      _scrollOffset = widget.scrollController.offset;
    });
  }

  @override
  void dispose() {
    widget.scrollController.removeListener(_onScroll);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 根据滚动偏移动态调整边缘渐变范围(可自定义系数)
    final edgeStop = 0.03 + (_scrollOffset / 1000).clamp(0.0, 0.05);
    return ShaderMask(
      shaderCallback: (Rect rect) {
        return LinearGradient(
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          colors: const [Colors.white, Colors.transparent, Colors.transparent, Colors.white],
          stops: [0.0, edgeStop, 1 - edgeStop, 1.0],
        ).createShader(rect);
      },
      blendMode: BlendMode.dstIn,
      child: ShaderMask(
        shaderCallback: (Rect rect) {
          return LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: const [Colors.white, Colors.transparent, Colors.transparent, Colors.white],
            stops: [0.0, edgeStop, 1 - edgeStop, 1.0],
          ).createShader(rect);
        },
        blendMode: BlendMode.dstIn,
        child: widget.child,
      ),
    );
  }
}

使用方式

将需要添加遮罩的列表或滚动组件传入FourEdgeGradientMask,并绑定对应的ScrollController即可:

final scrollController = ScrollController();

@override
Widget build(BuildContext context) {
  return FourEdgeGradientMask(
    scrollController: scrollController,
    child: ListView.builder(
      controller: scrollController,
      itemCount: 50,
      itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
    ),
  );
}

内容的提问来源于stack exchange,提问作者Dhanrajsinh Parmar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:57:18