dual_radial_gradient_border.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import 'package:flutter/material.dart';
  2. class DualRadialGradientBorderPainter extends CustomPainter {
  3. final double strokeWidth;
  4. final BorderRadius borderRadius;
  5. final RadialGradient leftToRightGradient;
  6. final RadialGradient rightToLeftGradient;
  7. final Color? backgroundColor;
  8. DualRadialGradientBorderPainter({
  9. this.strokeWidth = 1,
  10. double? radius,
  11. BorderRadius? borderRadius,
  12. required this.leftToRightGradient,
  13. required this.rightToLeftGradient,
  14. this.backgroundColor,
  15. }) : borderRadius = borderRadius ?? BorderRadius.circular(radius ?? 100);
  16. @override
  17. void paint(Canvas canvas, Size size) {
  18. final Rect rect = Rect.fromLTWH(
  19. strokeWidth / 2,
  20. strokeWidth / 2,
  21. size.width - strokeWidth,
  22. size.height - strokeWidth,
  23. );
  24. final RRect rrect = RRect.fromRectAndCorners(
  25. rect,
  26. topLeft: borderRadius.topLeft,
  27. topRight: borderRadius.topRight,
  28. bottomLeft: borderRadius.bottomLeft,
  29. bottomRight: borderRadius.bottomRight,
  30. );
  31. // 如果有背景色,先绘制背景
  32. if (backgroundColor != null) {
  33. final Paint backgroundPaint = Paint()
  34. ..style = PaintingStyle.fill
  35. ..color = backgroundColor!;
  36. canvas.drawRRect(rrect, backgroundPaint);
  37. }
  38. // 绘制第一层径向渐变边框 - 从左到右
  39. final Paint leftToRightPaint = Paint()
  40. ..style = PaintingStyle.stroke
  41. ..strokeWidth = strokeWidth
  42. ..shader = leftToRightGradient.createShader(rect);
  43. canvas.drawRRect(rrect, leftToRightPaint);
  44. // 绘制第二层径向渐变边框 - 从右到左
  45. final Paint rightToLeftPaint = Paint()
  46. ..style = PaintingStyle.stroke
  47. ..strokeWidth = strokeWidth
  48. ..shader = rightToLeftGradient.createShader(rect);
  49. canvas.drawRRect(rrect, rightToLeftPaint);
  50. }
  51. @override
  52. bool shouldRepaint(CustomPainter oldDelegate) => true;
  53. }
  54. class DualRadialGradientBorderContainer extends StatelessWidget {
  55. final Widget child;
  56. final double strokeWidth;
  57. final BorderRadius borderRadius;
  58. final RadialGradient leftToRightGradient;
  59. final RadialGradient rightToLeftGradient;
  60. final Color? backgroundColor;
  61. final EdgeInsetsGeometry padding;
  62. DualRadialGradientBorderContainer({
  63. super.key,
  64. required this.child,
  65. required this.leftToRightGradient,
  66. required this.rightToLeftGradient,
  67. this.strokeWidth = 1,
  68. double? radius,
  69. BorderRadius? borderRadius,
  70. this.padding = const EdgeInsets.all(8),
  71. this.backgroundColor,
  72. }) : borderRadius = borderRadius ?? BorderRadius.circular(radius ?? 100);
  73. @override
  74. Widget build(BuildContext context) {
  75. return CustomPaint(
  76. painter: DualRadialGradientBorderPainter(
  77. strokeWidth: strokeWidth,
  78. borderRadius: borderRadius,
  79. leftToRightGradient: leftToRightGradient,
  80. rightToLeftGradient: rightToLeftGradient,
  81. backgroundColor: backgroundColor,
  82. ),
  83. child: Container(
  84. padding: padding,
  85. child: child,
  86. ),
  87. );
  88. }
  89. }