round_widget.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import 'dart:math';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/painting.dart';
  4. class RoundPathWidget extends StatelessWidget {
  5. final Widget child;
  6. final double leftTopRadius;
  7. final double rightTopRadius;
  8. final double leftBottomRadius;
  9. final double rightBottomRadius;
  10. final PathShapeEnum pathShape;
  11. final double radius;
  12. RoundPathWidget(
  13. {@required this.child,
  14. this.radius = 0,
  15. this.pathShape = PathShapeEnum.CirclePath,
  16. this.leftTopRadius = 0,
  17. this.rightTopRadius = 0,
  18. this.leftBottomRadius = 0,
  19. this.rightBottomRadius = 0})
  20. : assert(child != null);
  21. @override
  22. Widget build(BuildContext context) {
  23. return ClipPath(
  24. clipper: RoundPathClipper(
  25. leftTopRadius: leftTopRadius,
  26. rightTopRadius: rightTopRadius,
  27. leftBottomRadius: leftBottomRadius,
  28. rightBottomRadius: rightBottomRadius,
  29. pathShape: pathShape,
  30. radius: radius),
  31. child: child,
  32. );
  33. }
  34. }
  35. ///枚举定义展示样式:圆形,圆角矩形,不同角不同圆角设置
  36. enum PathShapeEnum { CirclePath, RoundRect, PartRoundRect }
  37. class RoundPathClipper extends CustomClipper<Path> {
  38. final double leftTopRadius;
  39. final double rightTopRadius;
  40. final double leftBottomRadius;
  41. final double rightBottomRadius;
  42. final PathShapeEnum pathShape;
  43. final double radius;
  44. RoundPathClipper(
  45. {this.pathShape,
  46. this.radius,
  47. this.leftTopRadius,
  48. this.rightTopRadius,
  49. this.leftBottomRadius,
  50. this.rightBottomRadius});
  51. @override
  52. Path getClip(Size size) {
  53. final width = size.width;
  54. final height = size.height;
  55. final path = Path();
  56. if (PathShapeEnum.CirclePath == pathShape) {
  57. path.addOval(Rect.fromLTRB(0, 0, width, height));
  58. } else if (PathShapeEnum.RoundRect == pathShape) {
  59. path.addRRect(RRect.fromRectAndRadius(Rect.fromLTWH(0, 0, width, height), Radius.circular(radius)));
  60. } else {
  61. final leftTopRect =
  62. Rect.fromLTRB(0, 0, leftTopRadius * 2, leftTopRadius * 2);
  63. final leftBottomRect = Rect.fromLTRB(
  64. 0, height - leftBottomRadius * 2, leftBottomRadius * 2, height);
  65. final rightTopRect = Rect.fromLTRB(
  66. width - 2 * rightTopRadius, 0, width, rightTopRadius * 2);
  67. final rightBottomRect = Rect.fromLTRB(width - 2 * rightBottomRadius,
  68. height - rightBottomRadius * 2, width, height);
  69. //左上角 圆弧
  70. path.arcTo(leftTopRect, 180 / 180 * pi, 90 / 180 * pi, false);
  71. //右上角圆弧
  72. path.lineTo(width - rightTopRadius, 0);
  73. path.arcTo(rightTopRect, 270 / 180 * pi, 90 / 180 * pi, false);
  74. //右下角
  75. path.lineTo(width, height - rightBottomRadius);
  76. path.arcTo(rightBottomRect, 0, 90 / 180 * pi, false);
  77. //左下角
  78. path.lineTo(leftBottomRadius, height);
  79. path.arcTo(leftBottomRect, 90 / 180 * pi, 90 / 180 * pi, false);
  80. path.close();
  81. }
  82. return path;
  83. }
  84. @override
  85. bool shouldReclip(CustomClipper<Path> oldClipper) {
  86. return false;
  87. }
  88. }