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

如何为Flutter的CustomPaint组件添加圆角

如何为CustomPaint自定义形状添加圆角边缘?

问题描述

我尝试使用CustomPaint为自定义形状的组件添加圆角,但不知道如何为自定义形状添加圆角边缘。目前已完成形状绘制,但还未实现圆角效果。以下是自定义绘制的代码:

class RPSCustomPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint0 = Paint()
      ..color = const Color.fromARGB(255, 33, 150, 243)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.4900000095367432;

    Path path0 = Path();
    path0.moveTo(3.03, 197.85);
    path0.quadraticBezierTo(0.87, 47.28, 1.9, 1.36);
    path0.lineTo(207.0, 2.0);
    path0.lineTo(170.24, 197.9);
    path0.quadraticBezierTo(16.26, 197.13, 3.03, 197.85);
    canvas.drawPath(path0, paint0);
  }

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

解决方案

要给自定义路径的转角添加圆角,核心是在路径的转角位置用**圆弧(arcTo)**替代生硬的直线连接。步骤如下:

  1. 定义统一的圆角半径,方便调整;
  2. 调整原路径的直线端点,预留圆角的空间;
  3. 在每个转角处绘制圆弧过渡;
  4. 微调二次贝塞尔曲线的端点,保证路径闭合且平滑。

修改后的完整代码:

import 'dart:math' as math;

class RPSCustomPainter extends CustomPainter {
  // 可自定义圆角半径
  final double cornerRadius;

  RPSCustomPainter({this.cornerRadius = 8.0});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint0 = Paint()
      ..color = const Color.fromARGB(255, 33, 150, 243)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.4900000095367432
      ..strokeCap = StrokeCap.round; // 可选:让线条端点更圆润

    Path path0 = Path();
    final r = cornerRadius;

    // 起点:调整x坐标,预留左侧圆角空间
    path0.moveTo(3.03 + r, 197.85);

    // 左侧二次贝塞尔曲线:调整终点y坐标,避开左上角圆角
    path0.quadraticBezierTo(0.87, 47.28, 1.9, 1.36 + r);

    // 左上角圆角:从曲线终点过渡到右侧直线起点
    path0.arcTo(
      Rect.fromLTWH(1.9, 1.36, r, r),
      3 * math.pi / 2, // 起始角度:270度
      math.pi / 2, // 扫过角度:90度
      false,
    );

    // 顶部直线:调整终点x坐标,预留右上角圆角空间
    path0.lineTo(207.0 - r, 2.0);

    // 右上角圆角:从顶部直线终点过渡到右侧直线起点
    path0.arcTo(
      Rect.fromLTWH(207.0 - r, 2.0, r, r),
      math.pi, // 起始角度:180度
      math.pi / 2, // 扫过角度:90度
      false,
    );

    // 右侧直线:调整终点y坐标,预留右下角圆角空间
    path0.lineTo(170.24, 197.9 - r);

    // 右下角圆角:从右侧直线终点过渡到底部曲线起点
    path0.arcTo(
      Rect.fromLTWH(170.24 - r, 197.9 - r, r, r),
      math.pi / 2, // 起始角度:90度
      math.pi / 2, // 扫过角度:90度
      false,
    );

    // 底部二次贝塞尔曲线:调整起点x坐标,避开右下角圆角,终点回到起点附近
    path0.quadraticBezierTo(16.26, 197.13, 3.03 + r, 197.85);

    // 左下角圆角:从底部曲线终点过渡到起点
    path0.arcTo(
      Rect.fromLTWH(3.03, 197.85 - r, r, r),
      0, // 起始角度:0度
      math.pi / 2, // 扫过角度:90度
      false,
    );

    canvas.drawPath(path0, paint0);
  }

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

关键细节说明

  • arcTo参数:Rect.fromLTWH定义圆弧所在的矩形,后面两个参数分别是圆弧的起始角度和扫过角度,通过调整这两个值可以控制圆弧的方向;
  • 路径端点调整:所有直线的端点都向形状内部偏移了一个圆角半径,避免圆弧和原直线重叠;
  • strokeCap设置:可选添加strokeCap = StrokeCap.round,让线条的端点更圆润,提升整体视觉效果;
  • shouldRepaint优化:只有当圆角半径变化时才重绘,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:50:43