import 'package:flutter/material.dart'; ///tabbar样式下方横条固定宽度 class AbsUnderlineTabIndicator extends Decoration { const AbsUnderlineTabIndicator({ this.wantWidth, this.borderSide = const BorderSide(width: 2.0, color: Colors.white), this.insets = EdgeInsets.zero, }) : assert(borderSide != null), assert(insets != null); final BorderSide? borderSide; final double? wantWidth; final EdgeInsetsGeometry? insets; @override Decoration? lerpFrom(Decoration? a, double t) { if (a is UnderlineTabIndicator) { return UnderlineTabIndicator( borderSide: BorderSide.lerp(a.borderSide, borderSide!, t), insets: EdgeInsetsGeometry.lerp(a.insets, insets, t)!, ); } return super.lerpFrom(a, t); } @override Decoration? lerpTo(Decoration? b, double t) { if (b is UnderlineTabIndicator) { return UnderlineTabIndicator( borderSide: BorderSide.lerp(borderSide!, b.borderSide, t), insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!, ); } return super.lerpTo(b, t); } @override _UnderlinePainter createBoxPainter([VoidCallback? onChanged]) { return _UnderlinePainter(this, onChanged); } } class _UnderlinePainter extends BoxPainter { _UnderlinePainter(this.decoration, VoidCallback? onChanged) : super(onChanged); final AbsUnderlineTabIndicator decoration; BorderSide? get borderSide => decoration.borderSide; EdgeInsetsGeometry? get insets => decoration.insets; Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { final Rect indicator = insets!.resolve(textDirection).deflateRect(rect); //取中间坐标 double cw = (indicator.left + indicator.right) / 2; return Rect.fromLTWH( cw - decoration.wantWidth! / 2, indicator.bottom - borderSide!.width, decoration.wantWidth!, borderSide!.width); } @override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { assert(configuration.size != null); final Rect rect = offset & configuration.size!; final TextDirection textDirection = configuration.textDirection!; final Rect indicator = _indicatorRectFor(rect, textDirection).deflate(borderSide!.width / 2.0); final Paint paint = borderSide!.toPaint()..strokeCap = StrokeCap.round; canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint); } }