如何为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
相关产品推荐
相关产品推荐

