2023-07-10 17:50:31 +08:00
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------
|
|
|
|
|
|
// author:AllenSu
|
|
|
|
|
|
// date :2021/4/18 11:23 AM
|
|
|
|
|
|
// usage :自定义 UnderlineTabIndicator
|
|
|
|
|
|
// CSDN :https://blog.csdn.net/qq_42351033
|
|
|
|
|
|
// ------------------------------------------------------
|
|
|
|
|
|
|
2024-08-19 15:24:14 +08:00
|
|
|
|
class CustomUnderlineTabIndicator extends Decoration { // 控制器的宽度
|
2023-07-10 17:50:31 +08:00
|
|
|
|
|
|
|
|
|
|
const CustomUnderlineTabIndicator({
|
|
|
|
|
|
this.borderSide = const BorderSide(width: 2, color: Colors.white),
|
|
|
|
|
|
this.insets = EdgeInsets.zero,
|
|
|
|
|
|
this.strokeCap: StrokeCap.square,
|
|
|
|
|
|
this.width: 20,
|
|
|
|
|
|
}) : assert(borderSide != null),
|
|
|
|
|
|
assert(insets != null);
|
2024-08-19 15:24:14 +08:00
|
|
|
|
final BorderSide? borderSide;
|
|
|
|
|
|
final EdgeInsetsGeometry? insets;
|
|
|
|
|
|
final StrokeCap? strokeCap; // 控制器的边角形状
|
|
|
|
|
|
final double? width;
|
2023-07-10 17:50:31 +08:00
|
|
|
|
|
|
|
|
|
|
@override
|
2023-07-15 15:11:28 +08:00
|
|
|
|
Decoration? lerpFrom(Decoration? a, double t) {
|
2023-07-10 17:50:31 +08:00
|
|
|
|
if (a is CustomUnderlineTabIndicator) {
|
|
|
|
|
|
return CustomUnderlineTabIndicator(
|
2023-07-15 15:11:28 +08:00
|
|
|
|
borderSide: BorderSide.lerp(a.borderSide!, borderSide!, t),
|
|
|
|
|
|
insets: EdgeInsetsGeometry.lerp(a.insets!, insets!, t),
|
2023-07-10 17:50:31 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
2023-07-15 15:11:28 +08:00
|
|
|
|
return lerpFrom(a, t);
|
2023-07-10 17:50:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
2023-07-15 15:11:28 +08:00
|
|
|
|
Decoration? lerpTo(Decoration? b, double t) {
|
2023-07-10 17:50:31 +08:00
|
|
|
|
if (b is CustomUnderlineTabIndicator) {
|
|
|
|
|
|
return CustomUnderlineTabIndicator(
|
2023-07-15 15:11:28 +08:00
|
|
|
|
borderSide: BorderSide.lerp(borderSide!, b.borderSide!, t),
|
2023-07-10 17:50:31 +08:00
|
|
|
|
insets: EdgeInsetsGeometry.lerp(insets, b.insets, t),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
return super.lerpTo(b, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
2023-07-15 15:11:28 +08:00
|
|
|
|
_UnderlinePainter createBoxPainter([VoidCallback? onChanged]) {
|
|
|
|
|
|
return _UnderlinePainter(this, onChanged!);
|
2023-07-10 17:50:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
Path getClipPath(Rect rect, TextDirection textDirection) {
|
|
|
|
|
|
return Path()..addRect(_indicatorRectFor(rect, textDirection));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-15 15:11:28 +08:00
|
|
|
|
Rect _indicatorRectFor(Rect? rect, TextDirection? textDirection) {
|
2023-07-10 17:50:31 +08:00
|
|
|
|
assert(rect != null);
|
|
|
|
|
|
assert(textDirection != null);
|
2023-07-15 15:11:28 +08:00
|
|
|
|
final Rect indicator = insets!.resolve(textDirection).deflateRect(rect!);
|
2023-07-10 17:50:31 +08:00
|
|
|
|
|
|
|
|
|
|
// 希望的宽度
|
2023-07-15 15:11:28 +08:00
|
|
|
|
double wantWidth = width!;
|
2023-07-10 17:50:31 +08:00
|
|
|
|
// 取中间坐标
|
|
|
|
|
|
double cw = (indicator.left + indicator.right) / 2;
|
|
|
|
|
|
// 这里是核心代码
|
|
|
|
|
|
return Rect.fromLTWH(cw - wantWidth / 2,
|
2023-07-15 15:11:28 +08:00
|
|
|
|
indicator.bottom - borderSide!.width, wantWidth, borderSide!.width);
|
2023-07-10 17:50:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class _UnderlinePainter extends BoxPainter {
|
|
|
|
|
|
_UnderlinePainter(this.decoration, VoidCallback onChanged)
|
|
|
|
|
|
: assert(decoration != null),
|
|
|
|
|
|
super(onChanged);
|
|
|
|
|
|
|
2023-07-15 15:11:28 +08:00
|
|
|
|
final CustomUnderlineTabIndicator? decoration;
|
2023-07-10 17:50:31 +08:00
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
|
|
|
|
|
|
assert(configuration != null);
|
|
|
|
|
|
assert(configuration.size != null);
|
2023-07-15 15:11:28 +08:00
|
|
|
|
final Rect rect = offset & configuration.size!;
|
|
|
|
|
|
final TextDirection textDirection = configuration.textDirection!;
|
|
|
|
|
|
final Rect indicator = decoration!
|
2023-07-10 17:50:31 +08:00
|
|
|
|
._indicatorRectFor(rect, textDirection)
|
2023-07-15 15:11:28 +08:00
|
|
|
|
.deflate(decoration!.borderSide!.width / 2);
|
|
|
|
|
|
final Paint paint = decoration!.borderSide!.toPaint()
|
|
|
|
|
|
..strokeCap = decoration!.strokeCap!; // 这里修改控制器边角的形状
|
2023-07-10 17:50:31 +08:00
|
|
|
|
canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|