|
|
@@ -0,0 +1,113 @@ |
|
|
|
library flutter_bubble_tab_indicator; |
|
|
|
|
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:flutter/widgets.dart'; |
|
|
|
|
|
|
|
/// Used with [TabBar.indicator] to draw a bubble on the |
|
|
|
/// selected tab. |
|
|
|
/// |
|
|
|
/// The [indicatorHeight] defines the bubble height. |
|
|
|
/// The [indicatorColor] defines the bubble color. |
|
|
|
/// The [indicatorRadius] defines the bubble corner radius. |
|
|
|
/// The [tabBarIndicatorSize] specifies the type of TabBarIndicatorSize i.e label or tab. |
|
|
|
/// /// The selected tab bubble is inset from the tab's boundary by [insets] when [tabBarIndicatorSize] is tab. |
|
|
|
/// The selected tab bubble is applied padding by [padding] when [tabBarIndicatorSize] is label. |
|
|
|
/// tabvbar的背景装饰器 |
|
|
|
class BubbleTabIndicator extends Decoration { |
|
|
|
final double indicatorHeight; |
|
|
|
final Color indicatorColor; |
|
|
|
final double indicatorRadius; |
|
|
|
final EdgeInsetsGeometry padding; |
|
|
|
final EdgeInsetsGeometry insets; |
|
|
|
final TabBarIndicatorSize tabBarIndicatorSize; |
|
|
|
|
|
|
|
const BubbleTabIndicator({ |
|
|
|
this.indicatorHeight: 20.0, |
|
|
|
this.indicatorColor: Colors.greenAccent, |
|
|
|
this.indicatorRadius: 100.0, |
|
|
|
this.tabBarIndicatorSize = TabBarIndicatorSize.label, |
|
|
|
this.padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0), |
|
|
|
this.insets: const EdgeInsets.symmetric(horizontal: 5.0), |
|
|
|
}) : assert(indicatorHeight != null), |
|
|
|
assert(indicatorColor != null), |
|
|
|
assert(indicatorRadius != null), |
|
|
|
assert(padding != null), |
|
|
|
assert(insets != null); |
|
|
|
|
|
|
|
@override |
|
|
|
Decoration lerpFrom(Decoration a, double t) { |
|
|
|
if (a is BubbleTabIndicator) { |
|
|
|
return new BubbleTabIndicator( |
|
|
|
padding: EdgeInsetsGeometry.lerp(a.padding, padding, t), |
|
|
|
insets: EdgeInsetsGeometry.lerp(a.insets, insets, t), |
|
|
|
); |
|
|
|
} |
|
|
|
return super.lerpFrom(a, t); |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
Decoration lerpTo(Decoration b, double t) { |
|
|
|
if (b is BubbleTabIndicator) { |
|
|
|
return new BubbleTabIndicator( |
|
|
|
padding: EdgeInsetsGeometry.lerp(padding, b.padding, t), |
|
|
|
insets: EdgeInsetsGeometry.lerp(insets, b.insets, t), |
|
|
|
); |
|
|
|
} |
|
|
|
return super.lerpTo(b, t); |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
_BubblePainter createBoxPainter([VoidCallback onChanged]) { |
|
|
|
return new _BubblePainter(this, onChanged); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
class _BubblePainter extends BoxPainter { |
|
|
|
_BubblePainter(this.decoration, VoidCallback onChanged) |
|
|
|
: assert(decoration != null), |
|
|
|
super(onChanged); |
|
|
|
|
|
|
|
final BubbleTabIndicator decoration; |
|
|
|
|
|
|
|
double get indicatorHeight => decoration.indicatorHeight; |
|
|
|
Color get indicatorColor => decoration.indicatorColor; |
|
|
|
double get indicatorRadius => decoration.indicatorRadius; |
|
|
|
EdgeInsetsGeometry get padding => decoration.padding; |
|
|
|
EdgeInsetsGeometry get insets => decoration.insets; |
|
|
|
TabBarIndicatorSize get tabBarIndicatorSize => decoration.tabBarIndicatorSize; |
|
|
|
|
|
|
|
Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { |
|
|
|
assert(rect != null); |
|
|
|
assert(textDirection != null); |
|
|
|
|
|
|
|
Rect indicator = padding.resolve(textDirection).inflateRect(rect); |
|
|
|
|
|
|
|
if (tabBarIndicatorSize == TabBarIndicatorSize.tab) { |
|
|
|
indicator = insets.resolve(textDirection).deflateRect(rect); |
|
|
|
} |
|
|
|
|
|
|
|
return new Rect.fromLTWH( |
|
|
|
indicator.left, |
|
|
|
indicator.top, |
|
|
|
indicator.width, |
|
|
|
indicator.height, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { |
|
|
|
assert(configuration != null); |
|
|
|
assert(configuration.size != null); |
|
|
|
final Rect rect = Offset( |
|
|
|
offset.dx, (configuration.size.height / 2) - indicatorHeight / 2) & |
|
|
|
Size(configuration.size.width, indicatorHeight); |
|
|
|
final TextDirection textDirection = configuration.textDirection; |
|
|
|
final Rect indicator = _indicatorRectFor(rect, textDirection); |
|
|
|
final Paint paint = Paint(); |
|
|
|
paint.color = indicatorColor; |
|
|
|
paint.style = PaintingStyle.fill; |
|
|
|
canvas.drawRRect( |
|
|
|
RRect.fromRectAndRadius(indicator, Radius.circular(indicatorRadius)), |
|
|
|
paint); |
|
|
|
} |
|
|
|
} |