如何在Flutter中创建三角形徽章?
Flutter 三角形徽章实现方案
既然flutter_badges库无法实现三角形徽章的需求,不用硬改库,直接自己实现更简单。以下两种方案可以快速达到你要的效果:
方法一:ClipPath 快速实现基础三角形徽章
这种方式适合制作固定方向的三角角标,代码简洁易维护。
自定义徽章组件
class TriangleBadge extends StatelessWidget { final String text; final Color badgeColor; final Color textColor; final double size; const TriangleBadge({ super.key, required this.text, this.badgeColor = Colors.red, this.textColor = Colors.white, this.size = 30, }); @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: ClipPath( clipper: TriangleClipper(), child: Container( color: badgeColor, child: Center( child: Text( text, style: TextStyle( color: textColor, fontSize: size * 0.4, fontWeight: FontWeight.bold, ), ), ), ), ), ); } } // 自定义裁剪器,绘制右上角三角路径 class TriangleClipper extends CustomClipper<Path> { @override Path getClip(Size size) { final path = Path(); path.moveTo(size.width, 0); // 起点:右上角 path.lineTo(size.width, size.height); // 到右下角 path.lineTo(0, 0); // 到左上角 path.close(); // 闭合路径 return path; } @override bool shouldReclip(CustomClipper<Path> oldClipper) => false; }
使用示例
把徽章放在目标Widget的右上角,用Stack定位:
Stack( children: [ // 你的目标组件(比如卡片、图片) Container( width: 100, height: 100, color: Colors.grey[200], child: const Center(child: Text("目标组件")), ), // 三角形徽章 const Positioned( top: 0, right: 0, child: TriangleBadge(text: "3"), ), ], )
方法二:CustomPaint 实现带边框的灵活三角形
如果需要带边框、自定义三角方向等复杂样式,用CustomPaint直接绘制更灵活。
带边框的徽章组件
class CustomTriangleBadge extends StatelessWidget { final String text; final Color badgeColor; final Color textColor; final Color borderColor; final double borderWidth; final double size; const CustomTriangleBadge({ super.key, required this.text, this.badgeColor = Colors.red, this.textColor = Colors.white, this.borderColor = Colors.black, this.borderWidth = 1, this.size = 30, }); @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: CustomPaint( painter: TrianglePainter( color: badgeColor, borderColor: borderColor, borderWidth: borderWidth, ), child: Center( child: Text( text, style: TextStyle( color: textColor, fontSize: size * 0.4, fontWeight: FontWeight.bold, ), ), ), ), ); } } // 自定义绘制器,支持填充和边框 class TrianglePainter extends CustomPainter { final Color color; final Color borderColor; final double borderWidth; TrianglePainter({ required this.color, required this.borderColor, required this.borderWidth, }); @override void paint(Canvas canvas, Size size) { // 填充画笔 final fillPaint = Paint() ..color = color ..style = PaintingStyle.fill; // 边框画笔 final borderPaint = Paint() ..color = borderColor ..style = PaintingStyle.stroke ..strokeWidth = borderWidth; // 绘制右上角三角路径 final path = Path(); path.moveTo(size.width, 0); path.lineTo(size.width, size.height); path.lineTo(0, 0); path.close(); // 先画填充,再画边框 canvas.drawPath(path, fillPaint); canvas.drawPath(path, borderPaint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { final old = oldDelegate as TrianglePainter; return color != old.color || borderColor != old.borderColor || borderWidth != old.borderWidth; } }
调整三角方向
如果需要其他方向的三角,修改TrianglePainter中的路径即可:
- 左上角三角:
path.moveTo(0, 0); path.lineTo(size.width, 0); path.lineTo(0, size.height); path.close(); - 左下角三角:
path.moveTo(0, size.height); path.lineTo(size.width, size.height); path.lineTo(0, 0); path.close();
注意事项
- 如果文本过长,可调整
fontSize参数,或者根据文本长度动态计算徽章size; - 若文本位置偏移,可给
Text添加Padding,或用Transform.translate微调位置; - 两种方案都可以直接集成到现有项目,无需依赖第三方库,避免扩展flutter_badges带来的兼容性问题。
内容的提问来源于stack exchange,提问作者MICHEL Baptiste
相关产品推荐
相关产品推荐

