如何为Container实现渐变边框效果(适配半透明背景场景)
实现方案(Flutter原生无需第三方依赖)
方案1:CustomPaint自定义绘制(兼容性最优,全版本可用)
该方案可以精准控制仅在边框区域绘制径向渐变,完全不会干扰内部半透明背景的显示效果,代码实现如下:
import 'package:flutter/material.dart'; class GradientBorderCard extends StatelessWidget { final double borderWidth; final Gradient borderGradient; final Color bgColor; final double borderRadius; final Widget? child; const GradientBorderCard({ super.key, this.borderWidth = 2, required this.borderGradient, required this.bgColor, this.borderRadius = 16, this.child, }); @override Widget build(BuildContext context) { return CustomPaint( painter: _GradientBorderPainter( borderWidth: borderWidth, gradient: borderGradient, borderRadius: borderRadius, ), child: Container( padding: EdgeInsets.all(borderWidth), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(borderRadius), ), child: child, ), ); } } class _GradientBorderPainter extends CustomPainter { final double borderWidth; final Gradient gradient; final double borderRadius; _GradientBorderPainter({ required this.borderWidth, required this.gradient, required this.borderRadius, }); @override void paint(Canvas canvas, Size size) { final rect = Offset.zero & size; final outerRRect = RRect.fromRectAndRadius(rect, Radius.circular(borderRadius)); final innerRRect = RRect.fromRectAndRadius( rect.deflate(borderWidth), Radius.circular(borderRadius - borderWidth), ); // 采用奇偶填充规则,仅保留边框区域的绘制路径 final path = Path()..addRRect(outerRRect)..addRRect(innerRRect)..fillType = PathFillType.evenOdd; final paint = Paint()..shader = gradient.createShader(rect); canvas.drawPath(path, paint); } @override bool shouldRepaint(covariant _GradientBorderPainter oldDelegate) { return borderWidth != oldDelegate.borderWidth || gradient != oldDelegate.gradient || borderRadius != oldDelegate.borderRadius; } }
调用示例:
GradientBorderCard( borderWidth: 3, borderGradient: const RadialGradient( center: Alignment.center, radius: 1.2, colors: [Colors.purpleAccent, Colors.blueAccent, Colors.transparent], stops: [0.1, 0.6, 1], ), bgColor: Colors.black.withOpacity(0.3), // 自定义半透明背景色 borderRadius: 20, child: const SizedBox( width: 300, height: 200, child: Center(child: Text("卡片内容", style: TextStyle(color: Colors.white))), ), )
方案2:高版本Flutter原生实现(3.10+版本可用)
3.10及以上版本的Flutter已原生支持边框渐变属性,代码更简洁:
Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), border: Border.all( width: 3, gradient: const RadialGradient( center: Alignment.center, radius: 1.2, colors: [Colors.purpleAccent, Colors.blueAccent, Colors.transparent], stops: [0.1, 0.6, 1], ), ), color: Colors.black.withOpacity(0.3), // 自定义半透明背景色 ), width: 300, height: 200, child: const Center(child: Text("卡片内容", style: TextStyle(color: Colors.white))), )
两种方案都规避了双层容器叠加导致渐变透入内容区的问题,完全支持半透明背景,无需引入外部图片资源。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

