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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:42:32