基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bubble_tabIndicator.dart 3.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. library flutter_bubble_tab_indicator;
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/widgets.dart';
  4. /// Used with [TabBar.indicator] to draw a bubble on the
  5. /// selected tab.
  6. ///
  7. /// The [indicatorHeight] defines the bubble height.
  8. /// The [indicatorColor] defines the bubble color.
  9. /// The [indicatorRadius] defines the bubble corner radius.
  10. /// The [tabBarIndicatorSize] specifies the type of TabBarIndicatorSize i.e label or tab.
  11. /// /// The selected tab bubble is inset from the tab's boundary by [insets] when [tabBarIndicatorSize] is tab.
  12. /// The selected tab bubble is applied padding by [padding] when [tabBarIndicatorSize] is label.
  13. /// tabvbar的背景装饰器
  14. class BubbleTabIndicator extends Decoration {
  15. final double indicatorHeight;
  16. final Color indicatorColor;
  17. final double indicatorRadius;
  18. final EdgeInsetsGeometry padding;
  19. final EdgeInsetsGeometry insets;
  20. final TabBarIndicatorSize tabBarIndicatorSize;
  21. const BubbleTabIndicator({
  22. this.indicatorHeight: 20.0,
  23. this.indicatorColor: Colors.greenAccent,
  24. this.indicatorRadius: 100.0,
  25. this.tabBarIndicatorSize = TabBarIndicatorSize.label,
  26. this.padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
  27. this.insets: const EdgeInsets.symmetric(horizontal: 5.0),
  28. }) : assert(indicatorHeight != null),
  29. assert(indicatorColor != null),
  30. assert(indicatorRadius != null),
  31. assert(padding != null),
  32. assert(insets != null);
  33. @override
  34. Decoration lerpFrom(Decoration a, double t) {
  35. if (a is BubbleTabIndicator) {
  36. return new BubbleTabIndicator(
  37. padding: EdgeInsetsGeometry.lerp(a.padding, padding, t),
  38. insets: EdgeInsetsGeometry.lerp(a.insets, insets, t),
  39. );
  40. }
  41. return super.lerpFrom(a, t);
  42. }
  43. @override
  44. Decoration lerpTo(Decoration b, double t) {
  45. if (b is BubbleTabIndicator) {
  46. return new BubbleTabIndicator(
  47. padding: EdgeInsetsGeometry.lerp(padding, b.padding, t),
  48. insets: EdgeInsetsGeometry.lerp(insets, b.insets, t),
  49. );
  50. }
  51. return super.lerpTo(b, t);
  52. }
  53. @override
  54. _BubblePainter createBoxPainter([VoidCallback onChanged]) {
  55. return new _BubblePainter(this, onChanged);
  56. }
  57. }
  58. class _BubblePainter extends BoxPainter {
  59. _BubblePainter(this.decoration, VoidCallback onChanged)
  60. : assert(decoration != null),
  61. super(onChanged);
  62. final BubbleTabIndicator decoration;
  63. double get indicatorHeight => decoration.indicatorHeight;
  64. Color get indicatorColor => decoration.indicatorColor;
  65. double get indicatorRadius => decoration.indicatorRadius;
  66. EdgeInsetsGeometry get padding => decoration.padding;
  67. EdgeInsetsGeometry get insets => decoration.insets;
  68. TabBarIndicatorSize get tabBarIndicatorSize => decoration.tabBarIndicatorSize;
  69. Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
  70. assert(rect != null);
  71. assert(textDirection != null);
  72. Rect indicator = padding.resolve(textDirection).inflateRect(rect);
  73. if (tabBarIndicatorSize == TabBarIndicatorSize.tab) {
  74. indicator = insets.resolve(textDirection).deflateRect(rect);
  75. }
  76. return new Rect.fromLTWH(
  77. indicator.left,
  78. indicator.top,
  79. indicator.width,
  80. indicator.height,
  81. );
  82. }
  83. @override
  84. void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
  85. assert(configuration != null);
  86. assert(configuration.size != null);
  87. final Rect rect = Offset(
  88. offset.dx, (configuration.size.height / 2) - indicatorHeight / 2) &
  89. Size(configuration.size.width, indicatorHeight);
  90. final TextDirection textDirection = configuration.textDirection;
  91. final Rect indicator = _indicatorRectFor(rect, textDirection);
  92. final Paint paint = Paint();
  93. paint.color = indicatorColor;
  94. paint.style = PaintingStyle.fill;
  95. canvas.drawRRect(
  96. RRect.fromRectAndRadius(indicator, Radius.circular(indicatorRadius)),
  97. paint);
  98. }
  99. }