在 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:标签颜色
选择适合需求的方法即可实现各种自定义效果。