Flutter开发中如何实现如下图所示的反向border-radius效果
Flutter 实现反向border-radius(内凹圆角)的方案
反向圆角指的是边角向内凹陷的圆角效果,Flutter原生没有直接提供对应的组件属性,可通过以下两种常用方案实现:
方案1:原生自定义裁剪实现(无第三方依赖)
通过CustomClipper结合ClipPath手动绘制带反向圆角的路径,灵活性最高,可自定义任意位置的反向圆角:
- 第一步:定义自定义裁剪器和角位枚举
enum Corner { topLeft, topRight, bottomLeft, bottomRight } class InvertedRadiusClipper extends CustomClipper<Path> { final double radius; final List<Corner> corners; InvertedRadiusClipper({ required this.radius, this.corners = const [Corner.topLeft, Corner.topRight, Corner.bottomLeft, Corner.bottomRight] }); @override Path getClip(Size size) { final path = Path(); // 定位到左上角反向圆角起点 path.moveTo(0, radius); // 绘制左上角反向圆角 if (corners.contains(Corner.topLeft)) { path.arcToPoint(Offset(radius, 0), radius: Radius.circular(radius), clockwise: false); } else { path.lineTo(0, 0); path.lineTo(radius, 0); } // 上边缘到右上角反向圆角起点 path.lineTo(size.width - radius, 0); // 绘制右上角反向圆角 if (corners.contains(Corner.topRight)) { path.arcToPoint(Offset(size.width, radius), radius: Radius.circular(radius), clockwise: false); } else { path.lineTo(size.width, 0); path.lineTo(size.width, radius); } // 右边缘到右下角反向圆角起点 path.lineTo(size.width, size.height - radius); // 绘制右下角反向圆角 if (corners.contains(Corner.bottomRight)) { path.arcToPoint(Offset(size.width - radius, size.height), radius: Radius.circular(radius), clockwise: false); } else { path.lineTo(size.width, size.height); path.lineTo(size.width - radius, size.height); } // 下边缘到左下角反向圆角起点 path.lineTo(radius, size.height); // 绘制左下角反向圆角 if (corners.contains(Corner.bottomLeft)) { path.arcToPoint(Offset(0, size.height - radius), radius: Radius.circular(radius), clockwise: false); } else { path.lineTo(0, size.height); path.lineTo(0, size.height - radius); } path.close(); return path; } @override bool shouldReclip(covariant CustomClipper<Path> oldClipper) { return oldClipper is InvertedRadiusClipper && (oldClipper.radius != radius || oldClipper.corners != corners); } }
- 第二步:用裁剪器包裹目标组件即可生效
ClipPath( clipper: InvertedRadiusClipper(radius: 16, corners: [Corner.topLeft, Corner.bottomRight]), child: Container( width: 300, height: 200, color: Colors.blue, ), )
如果需要添加边框,可配合CustomPaint在对应路径上绘制描边即可。
方案2:借助第三方库快速实现
如果不需要高度自定义,可直接使用成熟的第三方库inner_border_radius,无需手动编写路径逻辑:
- 先在
pubspec.yaml中添加依赖
dependencies: inner_border_radius: ^最新版本号
- 直接给Container的decoration赋值即可
Container( width: 300, height: 200, decoration: BoxDecoration( color: Colors.blue, borderRadius: InnerBorderRadius.only( topLeft: Radius.circular(16), bottomRight: Radius.circular(16), ), ), )
注意事项
- 反向圆角无法直接使用Flutter原生
BoxShadow添加阴影,需要自定义阴影绘制逻辑,或配合Shadow属性绑定自定义ShapeBorder实现。 - 如需在反向圆角位置添加透明镂空效果,可将
ClipPath嵌套在Stack中,底层放背景内容即可。
内容的提问来源于stack exchange,提问作者Ibrahim 7
相关产品推荐
相关产品推荐

