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

Flutter中如何使用CustomPainter绘制带圆角的自定义内凹形状?

实现带圆角的自定义形状

你当前的路径全部使用直线段连接,所有拐角都是硬锐角,要实现圆角效果不需要复杂的路径计算,直接用二次贝塞尔曲线在每个拐角位置做圆弧过渡即可。

目标与当前实现

需要实现的形状效果:
目标形状

目前已实现的无圆角硬边效果:
当前实现效果

当前使用的绘制代码:

class NamePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint();
    paint.color = Colors.white;
    var path = Path();
    path.moveTo(size.width * 0.2, 0);
    path.lineTo(size.width * 0.1, size.height / 2);
    path.lineTo(size.width * 0.2, size.height);

    path.lineTo(size.width, size.height);
    path.lineTo(size.width, 0);
    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

修改后的带圆角实现

直接调整路径绘制逻辑,在每个拐角处预留圆角半径的长度,用quadraticBezierTo绘制圆角过渡段,支持自定义圆角大小:

class RoundedNamePainter extends CustomPainter {
  // 自定义圆角半径、填充色
  final double cornerRadius;
  final Color fillColor;

  RoundedNamePainter({
    this.cornerRadius = 16,
    this.fillColor = Colors.white,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = fillColor;
    final path = Path();
    final r = cornerRadius;
    // 左侧尖角X坐标
    final tipX = size.width * 0.1;
    // 尖角和矩形部分连接的颈部X坐标
    final neckX = size.width * 0.2;
    final midY = size.height / 2;

    // 定位到上边缘颈部圆角的起点
    path.moveTo(neckX + r, 0);
    // 绘制上边缘到右上角圆角起点
    path.lineTo(size.width - r, 0);
    // 右上角圆角
    path.quadraticBezierTo(size.width, 0, size.width, r);
    // 绘制右边缘到右下角圆角起点
    path.lineTo(size.width, size.height - r);
    // 右下角圆角
    path.quadraticBezierTo(size.width, size.height, size.width - r, size.height);
    // 绘制下边缘到下颈部圆角起点
    path.lineTo(neckX + r, size.height);
    // 下颈部圆角过渡
    path.quadraticBezierTo(neckX, size.height, tipX + r * 0.3, midY + r * 0.7);
    // 左侧尖角圆角
    path.quadraticBezierTo(tipX, midY, tipX + r * 0.3, midY - r * 0.7);
    // 上颈部圆角过渡,闭合路径
    path.quadraticBezierTo(neckX, 0, neckX + r, 0);

    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant RoundedNamePainter oldDelegate) {
    return oldDelegate.cornerRadius != cornerRadius 
        || oldDelegate.fillColor != fillColor;
  }
}

参数调整说明

  • 修改cornerRadius的数值可以全局调整圆角大小,数值越大圆角越圆润
  • 左侧尖角位置的圆角系数0.3/0.7可以根据视觉需求微调:数值越小尖角越锐利,数值越大尖角越圆润
  • 如果需要不同位置圆角大小不一致,单独修改对应贝塞尔曲线段的半径参数即可

内容的提问来源于stack exchange,提问作者Tar journey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:54:28