如何为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
相关产品推荐
相关产品推荐

