import 'dart:ui'; import 'package:flutter/material.dart'; class DottedBorderContainer extends StatelessWidget { final Widget child; final Color color; final double strokeWidth; final double gap; const DottedBorderContainer({ Key? key, required this.child, this.color = const Color(0xFFDDDDDD), this.strokeWidth = 2.5, this.gap = 5, }) : super(key: key); @override Widget build(BuildContext context) { return CustomPaint( painter: DottedBorderPainter( color: color, strokeWidth: strokeWidth, gap: gap, ), child: child, ); } } class DottedBorderPainter extends CustomPainter { final Color color; final double strokeWidth; final double gap; DottedBorderPainter({ required this.color, required this.strokeWidth, required this.gap, }); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ..strokeWidth = strokeWidth ..style = PaintingStyle.stroke; const radius = 10.0; final path = Path() ..addRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), Radius.circular(radius), ), ); _drawDashedPath(canvas, path, paint); } void _drawDashedPath(Canvas canvas, Path path, Paint paint) { final dashWidth = gap; final dashSpace = gap; double distance = 0.0; for (PathMetric pathMetric in path.computeMetrics()) { while (distance < pathMetric.length) { final nextDistance = distance + dashWidth; final segment = pathMetric.extractPath( distance, nextDistance > pathMetric.length ? pathMetric.length : nextDistance, ); canvas.drawPath(segment, paint); distance = nextDistance + dashSpace; } } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }