import 'dart:ui'; import 'package:flutter/material.dart'; class DashedRect extends StatelessWidget { final Color color; final double strokeWidth; final double gap; final Widget? child; final BorderRadius? borderRadius; const DashedRect({ super.key, this.color = Colors.black, this.strokeWidth = 1.0, this.gap = 5.0, this.child, this.borderRadius, }); @override Widget build(BuildContext context) { return CustomPaint( painter: _DashedRectPainter( color: color, strokeWidth: strokeWidth, gap: gap, borderRadius: borderRadius ?? BorderRadius.zero, ), child: child, ); } } class _DashedRectPainter extends CustomPainter { final Color color; final double strokeWidth; final double gap; final BorderRadius borderRadius; _DashedRectPainter({ required this.color, required this.strokeWidth, required this.gap, required this.borderRadius, }); @override void paint(Canvas canvas, Size size) { final Paint paint = Paint() ..color = color ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke; final Path path = Path() ..addRRect( RRect.fromRectAndCorners( Rect.fromLTWH(0, 0, size.width, size.height), topLeft: borderRadius.topLeft, topRight: borderRadius.topRight, bottomLeft: borderRadius.bottomLeft, bottomRight: borderRadius.bottomRight, ), ); Path dashedPath = Path(); for (PathMetric pathMetric in path.computeMetrics()) { double distance = 0.0; while (distance < pathMetric.length) { dashedPath.addPath( pathMetric.extractPath(distance, distance + gap), Offset.zero, ); distance += gap * 2; } } canvas.drawPath(dashedPath, paint); } @override bool shouldRepaint(covariant _DashedRectPainter oldDelegate) { return oldDelegate.color != color || oldDelegate.strokeWidth != strokeWidth || oldDelegate.gap != gap || oldDelegate.borderRadius != borderRadius; } }