在 Flutter 中,自定义 TabBar 的指示器(indicator)可以通过 TabBar 组件的 indicator 相关属性实现。以下是几种常见方法:
1. 基本自定义(颜色、大小、形状)
TabBar(
indicatorColor: Colors.red, // 指示器颜色
indicatorWeight: 4.0, // 指示器厚度
indicatorPadding: EdgeInsets.symmetric(horizontal: 10), // 内边距
indicator: BoxDecoration(
color: Colors.blue, // 背景色
borderRadius: BorderRadius.circular(8), // 圆角
),
tabs: [...],
)
2. 自定义指示器形状
TabBar(
indicator: CircleTabIndicator(
color: Colors.red,
radius: 4,
),
tabs: [...],
)
// 自定义圆形指示器
class CircleTabIndicator extends Decoration {
final Color color;
final double radius;
const CircleTabIndicator({required this.color, required this.radius});
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _CirclePainter(color: color, radius: radius);
}
}
class _CirclePainter extends BoxPainter {
final Color color;
final double radius;
_CirclePainter({required this.color, required this.radius});
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
final Paint paint = Paint()..color = color;
final Offset circleOffset = offset + Offset(cfg.size!.width / 2, cfg.size!.height - radius);
canvas.drawCircle(circleOffset, radius, paint);
}
}
3. 下划线渐变效果
TabBar(
indicator: CustomUnderlineTabIndicator(
borderSide: BorderSide(width: 3.0, color: Colors.red),
insets: EdgeInsets.symmetric(horizontal: 20),
),
tabs: [...],
)
// 自定义下划线指示器
class CustomUnderlineTabIndicator extends Decoration {
final BorderSide borderSide;
final EdgeInsetsGeometry insets;
const CustomUnderlineTabIndicator({
this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
this.insets = EdgeInsets.zero,
});
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _UnderlinePainter(borderSide: borderSide, insets: insets);
}
}
class _UnderlinePainter extends BoxPainter {
final BorderSide borderSide;
final EdgeInsetsGeometry insets;
_UnderlinePainter({required this.borderSide, required this.insets});
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
final Rect rect = offset & cfg.size!;
final Rect indicator = insets.resolve(TextDirection.ltr).deflateRect(rect);
final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.round;
canvas.drawLine(
Offset(indicator.left, indicator.bottom - borderSide.width / 2),
Offset(indicator.right, indicator.bottom - borderSide.width / 2),
paint,
);
}
}
4. 完全自定义指示器
通过 TabBar 的 indicator 属性传入自定义 Decoration:
TabBar(
indicator: MyCustomIndicator(),
tabs: [...],
)
class MyCustomIndicator extends Decoration {
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return MyCustomPainter();
}
}
class MyCustomPainter extends BoxPainter {
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
// 在这里实现自定义绘制逻辑
// 使用 canvas.drawRect(), canvas.drawPath() 等方法
}
}
主要属性说明:
indicatorColor:指示器颜色
indicatorWeight:指示器线条粗细
indicatorPadding:指示器内边距
indicator:完全自定义的指示器装饰
labelColor/unselectedLabelColor:标签颜色
选择适合需求的方法即可实现各种自定义效果。