如何为自定义形状的PopupMenuButton设置边框颜色?
原有的TooltipShape类仅定义了形状路径,但没有实现边框的绘制逻辑,默认使用了BorderSide.none,要让它支持自定义边框颜色,需要对类做如下修改:
1. 修改TooltipShape类,支持自定义边框
允许通过构造参数传入BorderSide,并在paint方法中绘制边框路径,同时调整内部路径和尺寸计算:
class TooltipShape extends ShapeBorder { final BorderSide side; final BorderRadiusGeometry borderRadius; const TooltipShape({ this.side = const BorderSide(), this.borderRadius = BorderRadius.zero, }); @override EdgeInsetsGeometry get dimensions => EdgeInsets.all(side.width); @override Path getInnerPath( Rect rect, { TextDirection? textDirection, }) { final Path path = Path(); final RRect rrect = borderRadius.resolve(textDirection).toRRect(rect).deflate(side.width); // 生成偏移边框宽度的内部路径,避免内容被边框遮挡 path.moveTo(0, 10 - side.width); path.quadraticBezierTo(side.width, side.width, 10, side.width); path.lineTo(rrect.width - 30, side.width); path.lineTo(rrect.width - 20, side.width - 10); path.lineTo(rrect.width - 10, side.width); path.quadraticBezierTo(rrect.width, side.width, rrect.width, 10); path.lineTo(rrect.width, rrect.height - 10); path.quadraticBezierTo( rrect.width, rrect.height - side.width, rrect.width - 10, rrect.height - side.width); path.lineTo(10, rrect.height - side.width); path.quadraticBezierTo(side.width, rrect.height - side.width, side.width, rrect.height - 10); return path; } @override Path getOuterPath(Rect rect, {TextDirection? textDirection}) { final Path path = Path(); final RRect rrect = borderRadius.resolve(textDirection).toRRect(rect); path.moveTo(0, 10); path.quadraticBezierTo(0, 0, 10, 0); path.lineTo(rrect.width - 30, 0); path.lineTo(rrect.width - 20, -10); path.lineTo(rrect.width - 10, 0); path.quadraticBezierTo(rrect.width, 0, rrect.width, 10); path.lineTo(rrect.width, rrect.height - 10); path.quadraticBezierTo( rrect.width, rrect.height, rrect.width - 10, rrect.height); path.lineTo(10, rrect.height); path.quadraticBezierTo(0, rrect.height, 0, rrect.height - 10); return path; } @override void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { final paint = Paint() ..style = PaintingStyle.stroke ..color = side.color ..strokeWidth = side.width; canvas.drawPath(getOuterPath(rect, textDirection: textDirection), paint); } @override ShapeBorder scale(double t) => TooltipShape( side: side.scale(t), borderRadius: borderRadius * t, ); }
2. 使用带边框的TooltipShape
在PopupMenuButton中指定shape参数时,传入自定义的BorderSide来设置边框颜色和宽度:
PopupMenuButton( offset: const Offset(0, 50), shape: const TooltipShape( side: BorderSide( color: Colors.blue, // 设置边框颜色 width: 1.0, // 设置边框宽度 ), ), // 其他参数... )
关键说明
- 构造函数新增
side和borderRadius参数,让样式配置更灵活 paint方法通过canvas.drawPath绘制外部路径的边框,直接使用传入的BorderSide属性getInnerPath调整了路径偏移量,确保菜单内部内容不会被边框遮挡scale方法同步更新边框和圆角的缩放逻辑,保持形状一致性
内容的提问来源于stack exchange,提问作者user5182503
相关产品推荐
相关产品推荐

