flutter如何自定义tab indicator

在Flutter中如何自定义TabBar的indicator样式?比如修改indicator的颜色、宽度、圆角或添加动画效果?官方文档提供的默认选项比较有限,想实现类似Material Design中的自定义下划线效果,或者完全替换成其他形状的指示器。请问有没有具体的代码示例或推荐的方式来实现高度定制化的Tab indicator?

2 回复

使用TabBarindicator属性,可自定义BoxDecorationBorderTabIndicatorSize。示例:

indicator: BoxDecoration(
  color: Colors.blue,
  borderRadius: BorderRadius.circular(8),
),

更多关于flutter如何自定义tab indicator的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在 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. 完全自定义指示器

通过 TabBarindicator 属性传入自定义 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:标签颜色

选择适合需求的方法即可实现各种自定义效果。

回到顶部