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

Flutter中如何自定义绘制带凸起及文字的TabBar?

Flutter实现凸起效果及文字添加方案

你已经搞定了加号按钮的自定义绘制,接下来要做的凸起效果和文字,用CustomPaint就能轻松实现,下面给你具体的代码和调整思路:

1. 自定义凸起绘制器(带文字)

先写一个CustomPainter,既负责画凸起的形状,也能在上面绘制文字:

class BumpPainter extends CustomPainter {
  final Color bumpColor;
  final String text;
  final TextStyle textStyle;

  BumpPainter({required this.bumpColor, required this.text, required this.textStyle});

  @override
  void paint(Canvas canvas, Size size) {
    // 绘制凸起的画笔
    final paint = Paint()..color = bumpColor..style = PaintingStyle.fill;

    // 构建凸起的路径:底部是矩形,顶部中间做弧形凸起
    final path = Path();
    path.moveTo(0, size.height); // 左下角
    path.lineTo(0, size.height * 0.3); // 左上角往上到凸起起始点
    // 左半弧:从左上起始点到顶部中间,用二次贝塞尔曲线
    path.quadraticBezierTo(
      size.width * 0.25, // 左控制点x
      0, // 左控制点y(凸起最高点)
      size.width * 0.5, // 弧顶x(中心)
      size.height * 0.15, // 弧顶y(比控制点低一点,形成圆润的凸起)
    );
    // 右半弧:从顶部中间到右上起始点
    path.quadraticBezierTo(
      size.width * 0.75, // 右控制点x
      0, // 右控制点y
      size.width, // 右上起始点x
      size.height * 0.3, // 右上起始点y
    );
    path.lineTo(size.width, size.height); // 右下角
    path.close(); // 闭合路径

    canvas.drawPath(path, paint);

    // 绘制文字:自动居中在凸起顶部
    final textPainter = TextPainter(
      text: TextSpan(text: text, style: textStyle),
      textAlign: TextAlign.center,
      textDirection: TextDirection.ltr,
    );
    textPainter.layout(minWidth: 0, maxWidth: size.width);
    // 计算文字偏移,让文字在凸起顶部居中
    final textOffset = Offset(
      (size.width - textPainter.width) / 2,
      (size.height * 0.15 - textPainter.height) / 2,
    );
    textPainter.paint(canvas, textOffset);
  }

  @override
  bool shouldRepaint(covariant BumpPainter oldDelegate) {
    // 只有当颜色、文字或样式变化时才重绘
    return oldDelegate.bumpColor != bumpColor ||
        oldDelegate.text != text ||
        oldDelegate.textStyle != textStyle;
  }
}

2. 和你的加号按钮组合使用

用Stack布局把凸起放在加号按钮的下方(或者你需要的位置),示例代码:

Stack(
  alignment: Alignment.bottomCenter,
  children: [
    // 你已经实现的自定义加号按钮
    CustomPaint(
      size: const Size(60, 60),
      painter: YourPlusButtonPainter(), // 替换成你自己的加号绘制器
    ),
    // 凸起效果+文字
    CustomPaint(
      size: const Size(120, 40),
      painter: BumpPainter(
        bumpColor: Colors.blue.shade500,
        text: "添加",
        textStyle: const TextStyle(
          color: Colors.white,
          fontSize: 16,
          fontWeight: FontWeight.bold,
        ),
      ),
    ),
  ],
)

3. 调整技巧

  • 要改凸起的高度、弧度:调整quadraticBezierTo里的控制点坐标就行,比如把0改成-5,凸起会更高;把size.width * 0.25改成size.width * 0.3,弧度会更平缓
  • 文字位置不对:微调textOffset里的数值,比如y值加2,文字就往下挪一点
  • 想减少组件层级:可以把加号按钮的绘制逻辑合并到BumpPainter里,在同一个paint方法里先画凸起再画加号

内容的提问来源于stack exchange,提问作者Stéphane de Luca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:20:23