在日常开发中,为了提升视觉效果,我们经常需要给组件加上一些特殊的装饰性边框。今天就来教大家如何实现一个支持圆角、渐变色、虚线效果的容器边框组件。
🧩 功能概览
我们要做的组件具备以下特点:
- ✅ 支持自定义圆角
- ✅ 支持自定义虚线长度和间距
- ✅ 支持线宽设置
- ✅ 支持渐变色彩绘制
🛠 实现步骤详解
步骤 1:创建 CustomPainter
我们通过继承 CustomPainter 来实现绘图逻辑。核心在于使用 Canvas 绘制带有虚线效果的圆角矩形路径,并为其填充渐变色。
class _GradientDashedRRectPainter extends CustomPainter {
final LinearGradient gradient;
final double borderRadius;
final double strokeWidth;
final double dashLength;
final double dashGap;
const _GradientDashedRRectPainter({
required this.gradient,
required this.borderRadius,
required this.strokeWidth,
required this.dashLength,
required this.dashGap,
});
@override
void paint(Canvas canvas, Size size) {
final rect = Offset.zero & size;
if (rect.isEmpty) return;
final paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..isAntiAlias = true
..shader = gradient.createShader(rect);
final rrect = RRect.fromRectAndRadius(
rect.deflate(strokeWidth / 2),
Radius.circular(borderRadius));
final path = Path()..addRRect(rrect);
for (final metric in path.computeMetrics()) {
double distance = 0;
while (distance < metric.length) {
final end = min(distance + dashLength, metric.length);
canvas.drawPath(metric.extractPath(distance, end), paint);
distance += dashLength + dashGap;
}
}
}
@override
bool shouldRepaint(covariant _GradientDashedRRectPainter oldDelegate) {
return oldDelegate.gradient != gradient ||
oldDelegate.borderRadius != borderRadius ||
oldDelegate.strokeWidth != strokeWidth ||
oldDelegate.dashLength != dashLength ||
oldDelegate.dashGap != dashGap;
}
}
步骤 2:封装成可复用的 Widget
我们将上面的绘制类包装成一个通用的 DashedLineWidget 组件,方便在项目中反复使用。
class DashedLineWidget extends StatefulWidget {
final Widget child;
final double? borderRadius;
final double? strokeWidth;
final double? dashLength;
final double? dashGap;
final LinearGradient? gradient;
const DashedLineWidget({
super.key,
required this.child,
this.borderRadius,
this.strokeWidth,
this.dashLength,
this.dashGap,
this.gradient,
});
@override
State<DashedLineWidget> createState() => _DashedLineWidgetState();
}
class _DashedLineWidgetState extends State<DashedLineWidget> {
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _GradientDashedRRectPainter(
gradient: widget.gradient ??
const LinearGradient(
colors: [Color(0xff3DEEFF), Color(0xffFF62F7)],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: widget.borderRadius ?? 0,
strokeWidth: widget.strokeWidth ?? 1,
dashLength: widget.dashLength ?? 5,
dashGap: widget.dashGap ?? 3,
),
child: Padding(
padding: EdgeInsets.all(widget.strokeWidth ?? 1),
child: widget.child,
),
);
}
}
📖 使用示例大全
示例 1:基础用法
最简单的使用方式,无需任何参数,使用默认的青色到粉色渐变:
DashedLineWidget(
child: Container(
width: 200,
height: 100,
alignment: Alignment.center,
child: Text("默认虚线边框"),
),
)
效果:8像素圆角、1像素线宽、青粉渐变
示例 2:自定义圆角 + 线宽
想要更粗的边框和更大的圆角?调整参数即可:
DashedLineWidget(
borderRadius: 20.0, // 圆角20像素
strokeWidth: 2.0, // 线宽2像素
child: Container(
width: 200,
height: 100,
alignment: Alignment.center,
child: Text("粗边框大圆角"),
),
)
示例 3:多彩渐变
从左到右的彩虹渐变效果:
DashedLineWidget(
gradient: const LinearGradient(
colors: [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
Colors.blue,
Colors.indigo,
Colors.purple,
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
borderRadius: 12.0,
strokeWidth: 2.0,
child: Container(
width: 200,
height: 100,
alignment: Alignment.center,
child: Text("彩虹渐变边框"),
),
)
示例 4:竖向渐变 + 短虚线
竖向渐变风格,配合更短的虚线段:
DashedLineWidget(
gradient: const LinearGradient(
colors: [Color(0xFF667eea), Color(0xFF764ba2)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
borderRadius: 8.0,
dashLength: 4.0, // 短虚线
dashGap: 2.0, // 紧凑间距
child: Container(
width: 200,
height: 100,
alignment: Alignment.center,
child: Text("竖向渐变短虚线"),
),
)
示例 5:实用卡片场景
结合实际业务场景,作为卡片容器使用:
DashedLineWidget(
borderRadius: 16.0,
strokeWidth: 1.5,
dashLength: 8.0,
dashGap: 4.0,
gradient: const LinearGradient(
colors: [Color(0xFF00c6ff), Color(0xFF0072ff)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
child: Card(
elevation: 0,
color: Color(0xFFF5F8FA),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star, color: Color(0xFF0072ff), size: 40),
SizedBox(height: 8),
Text("精选内容", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text("这是卡片内的描述文字", style: TextStyle(color: Colors.grey)),
],
),
),
),
)
💡 小结
通过本文介绍的方法,我们可以轻松地为任意组件添加美观的虚线渐变边框,具备以下高度可定制的参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
| borderRadius | 圆角大小 | 8.0 |
| strokeWidth | 边框线宽 | 1.0 |
| dashLength | 虚线段长度 | 5.0 |
| dashGap | 虚线间距 | 3.0 |
| gradient | 渐变颜色 | 青→粉 |
非常适合用于卡片、按钮、弹窗、封面等 UI 场景中,能够有效提升界面的视觉层次感和设计感。
如果你觉得有用,欢迎分享给更多小伙伴! 🚀