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

如何为Flutter自定义斜切CustomClipper的斜角添加圆角?

实现带圆角的斜切容器

我有两个容器,一个右侧做斜切处理,另一个左侧做斜切处理,现在无法为斜切角添加圆角,需要给所有斜切角加上圆角,该如何实现?

原Clipper代码:

class LeftSkewClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path = Path();
    path.moveTo(0, 0);
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(15, size.height);

    path.close();

    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

class RightSkewClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path = Path();
    path.moveTo(0, 0);
    path.lineTo(size.width - 15, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

修改后的实现方案

通过Path.arcToPoint()方法为每个角(包括斜切的特殊角)添加圆角,同时将圆角半径和斜切偏移设为可配置参数,方便调整样式:

class LeftSkewClipper extends CustomClipper<Path> {
  final double borderRadius;
  final double skewOffset;

  LeftSkewClipper({this.borderRadius = 8.0, this.skewOffset = 15.0});

  @override
  Path getClip(Size size) {
    Path path = Path();
    // 左上角圆角
    path.moveTo(borderRadius, 0);
    path.arcToPoint(Offset(0, borderRadius), radius: Radius.circular(borderRadius));
    // 左下角圆角
    path.lineTo(0, size.height - borderRadius);
    path.arcToPoint(Offset(borderRadius, size.height), radius: Radius.circular(borderRadius));
    // 斜切带圆角的右下角
    final skewStartX = skewOffset + borderRadius;
    path.lineTo(skewStartX, size.height);
    path.arcToPoint(Offset(skewOffset, size.height - borderRadius), radius: Radius.circular(borderRadius));
    // 右侧边到右上角区域
    path.lineTo(size.width - borderRadius, size.height - borderRadius);
    path.lineTo(size.width - borderRadius, borderRadius);
    // 右上角圆角
    path.arcToPoint(Offset(size.width, 0), radius: Radius.circular(borderRadius));
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

class RightSkewClipper extends CustomClipper<Path> {
  final double borderRadius;
  final double skewOffset;

  RightSkewClipper({this.borderRadius = 8.0, this.skewOffset = 15.0});

  @override
  Path getClip(Size size) {
    Path path = Path();
    // 左上角圆角
    path.moveTo(borderRadius, 0);
    path.arcToPoint(Offset(0, borderRadius), radius: Radius.circular(borderRadius));
    // 左下角圆角
    path.lineTo(0, size.height - borderRadius);
    path.arcToPoint(Offset(borderRadius, size.height), radius: Radius.circular(borderRadius));
    // 右下角圆角
    path.lineTo(size.width - borderRadius, size.height);
    path.arcToPoint(Offset(size.width, size.height - borderRadius), radius: Radius.circular(borderRadius));
    // 斜切带圆角的右上角
    final skewEndX = size.width - skewOffset - borderRadius;
    path.lineTo(size.width - skewOffset, borderRadius);
    path.arcToPoint(Offset(skewEndX, 0), radius: Radius.circular(borderRadius));
    // 回到起点
    path.lineTo(borderRadius, 0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

效果对比

当前实现效果:
当前效果

修改后可达到的期望效果:
期望效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:47:19