Flutter如何实现中心带圆角的容器缺口?基于CustomPainter实现BottomAppBar弧形缺口的方法问询
实现带圆角弧形缺口的BottomAppBar
我明白你的需求——默认的CircularNotchedRectangle做出来的缺口太“生硬”,想要一个中心位置带圆角的弧形缺口对吧?我们可以通过自定义NotchedShape结合路径绘制的思路来实现,下面是具体的步骤和代码:
1. 自定义带圆角弧形缺口的Shape类
我们创建一个RoundedArcNotchedShape类,继承NotchedShape,重写getOuterPath方法来绘制我们想要的缺口路径:
class RoundedArcNotchedShape extends NotchedShape { // 可自定义的缺口参数,按需调整 final double notchWidth; final double notchHeight; final double notchRadius; RoundedArcNotchedShape({ this.notchWidth = 80.0, this.notchHeight = 30.0, this.notchRadius = 12.0, }); @override Path getOuterPath(Rect host, Rect? guest) { if (guest == null) return Path()..addRect(host); // 计算缺口的中心位置(与FloatingActionButton自动对齐) final double notchCenterX = guest.center.dx; // 缺口左右边界 final double leftEdge = notchCenterX - notchWidth / 2; final double rightEdge = notchCenterX + notchWidth / 2; // 缺口底部的Y坐标 final double notchBottomY = host.top + notchHeight; return Path() // 从BottomAppBar左上角开始绘制 ..moveTo(host.left, host.top) // 画到缺口左边界顶部 ..lineTo(leftEdge, host.top) // 绘制左圆角弧形 ..quadraticBezierTo( leftEdge, notchBottomY, leftEdge + notchRadius, notchBottomY, ) // 绘制缺口底部直线 ..lineTo(rightEdge - notchRadius, notchBottomY) // 绘制右圆角弧形 ..quadraticBezierTo( rightEdge, notchBottomY, rightEdge, host.top, ) // 完成剩余边界绘制并闭合路径 ..lineTo(host.right, host.top) ..lineTo(host.right, host.bottom) ..lineTo(host.left, host.bottom) ..close(); } }
参数说明:
notchWidth:缺口的横向宽度,可根据FloatingActionButton的尺寸调整notchHeight:缺口向下凹陷的深度notchRadius:缺口两端的圆角半径,控制圆角的圆润程度
2. 将自定义Shape应用到BottomAppBar
把原来的CircularNotchedRectangle()替换成我们的自定义Shape,整合到你的代码中:
BottomAppBar( // 使用自定义缺口Shape,可按需调整参数 shape: RoundedArcNotchedShape( notchWidth: 90.0, notchHeight: 32.0, notchRadius: 14.0, ), child: Container( height: MediaQuery.of(context).size.height * .07, width: MediaQuery.of(context).size.width, alignment: Alignment.center, decoration: BoxDecoration( gradient: LinearGradient( end: Alignment.centerRight, begin: Alignment.centerLeft, colors: [ blueColor, lightColor, ], ), ), child: Padding( padding: const EdgeInsets.only(left: 16, right: 16), child: Row( children: [ Image.asset( "assets/images/home.png", height: MediaQuery.of(context).size.height * .035, width: MediaQuery.of(context).size.width * .3, ), const Spacer(), Image.asset( "assets/images/cart.png", height: MediaQuery.of(context).size.height * .035, width: MediaQuery.of(context).size.width * .3, ), ], ), ), ), )
额外说明
- 这个自定义Shape会自动和页面中的
FloatingActionButton对齐,没有FAB的情况下也能正常显示中心缺口 - 如果需要调整缺口的弧形曲线,可以把
quadraticBezierTo换成arcTo来绘制不同弧度的曲线,满足更个性化的需求
内容的提问来源于stack exchange,提问作者Mariam Younes
相关产品推荐
相关产品推荐

