You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter教程:如何实现带圆角的自定义下划线Tab指示器

Flutter 为 UnderlineTabIndicator 添加圆角的解决方案

UnderlineTabIndicator 本身确实没有内置 borderRadius 属性,要实现带圆角的Tab下划线,最可靠的方式是自定义一个继承自 Decoration 的Tab指示器,通过Canvas精准绘制带圆角的底部线条。

自定义圆角下划线指示器

先创建一个自定义的 RoundedUnderlineTabIndicator 类:

class RoundedUnderlineTabIndicator extends Decoration {
  final BorderSide borderSide;
  final EdgeInsetsGeometry insets;
  final BorderRadius borderRadius;

  const RoundedUnderlineTabIndicator({
    this.borderSide = const BorderSide(width: 2.0, color: Colors.blue),
    this.insets = EdgeInsets.zero,
    this.borderRadius = const BorderRadius.all(Radius.circular(4.0)),
  });

  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    return _RoundedUnderlinePainter(this, onChanged);
  }
}

class _RoundedUnderlinePainter extends BoxPainter {
  final RoundedUnderlineTabIndicator decoration;

  _RoundedUnderlinePainter(this.decoration, VoidCallback? onChanged)
      : super(onChanged);

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    final Rect rect = offset & configuration.size;
    final EdgeInsets insets = decoration.insets.resolve(configuration.textDirection);
    final Rect indicatorRect = insets.deflateRect(rect);

    // 定位下划线:贴住Tab底部,高度等于borderSide的宽度
    final Paint paint = decoration.borderSide.toPaint()
      ..style = PaintingStyle.fill;

    final Rect underlineRect = Rect.fromLTWH(
      indicatorRect.left,
      indicatorRect.bottom - decoration.borderSide.width,
      indicatorRect.width,
      decoration.borderSide.width,
    );

    // 绘制仅顶部带圆角的矩形(底部圆角无需显示)
    canvas.drawRRect(
      RRect.fromRectAndCorners(
        underlineRect,
        topLeft: decoration.borderRadius.topLeft,
        topRight: decoration.borderRadius.topRight,
        bottomLeft: Radius.zero,
        bottomRight: Radius.zero,
      ),
      paint,
    );
  }
}

在你的TabBar中替换使用

把原本的 UnderlineTabIndicator 替换成自定义的指示器,并设置需要的圆角参数:

TabBar(
  controller: _tabController,
  labelStyle: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
  unselectedLabelColor: Colors.black,
  labelColor: Colors.black,
  indicatorSize: TabBarIndicatorSize.tab,
  // 使用自定义圆角指示器
  indicator: RoundedUnderlineTabIndicator(
    borderSide: BorderSide(
      width: 5.0,
      color: HexColor("2C7381"),
    ),
    insets: EdgeInsets.symmetric(horizontal: 10.0, vertical: 0),
    borderRadius: BorderRadius.circular(5.0), // 自定义圆角大小
  ),
  tabs: [
    Container(
      color: Colors.amber,
      child: Padding(
        padding: const EdgeInsets.only(bottom: 10),
        child: Column(
          children: [
            Image.asset(
              _activeIndex == 0
                  ? "assets/icons/dummy1.png"
                  : "assets/icons/dummy2.png",
              height: 20,
            ),
            SizedBox(height: 5),
            Text(
              "TAB 0",
              style: Dummytheme.text14theme,
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
    ),
    // 其他Tab项...
  ],
)

原方案失效的原因

ShapeDecoration 是基于Tab的整体尺寸进行绘制的,无法精准定位到底部的小范围区域;而自定义Painter可以直接控制绘制的位置、形状,完美适配Tab底部下划线的圆角需求。


内容的提问来源于stack exchange,提问作者Alifa Al Farizi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:55:17