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

Flutter中CircularNotchedRectangle异常求助:BottomAppBar无缺口等问题

问题解决:BottomAppBar缺口异常与底部白色区域问题

核心问题原因

  1. FAB脱离默认布局关联:你用Stack+Positioned手动定位FloatingActionButton,打破了Flutter内置的FAB与BottomAppBar的布局关联逻辑。CircularNotchedRectangle的缺口是基于FAB的默认位置、尺寸计算生成的,手动移动FAB后,BottomAppBar无法获取正确的FAB信息,自然无法生成匹配的缺口。
  2. 中间Container高度异常:底部白色区域来自Row中间的Container——你设置了height: screenHeight * 0.9,这个高度远大于BottomAppBar的screenHeight * 0.08,导致Container超出BottomAppBar范围延伸到屏幕底部,再加上notch计算错误,就出现了随notchMargin变化的白色区域。

修复方案

1. 恢复FAB与BottomAppBar的布局关联

去掉Stack+Positioned,让FAB处于Scaffold的默认FAB布局流程中,通过调整FAB自身尺寸或自定义FloatingActionButtonLocation来实现位置需求,而非手动定位。

2. 修正中间Container的高度

将中间Container的高度改为与BottomAppBar一致,通过布局对齐而非硬编码高度来放置文本,避免超出BottomAppBar范围。

修改后的完整代码示例

floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: SizedBox(
  height: screenHeight * 0.15,
  width: screenWidth * 0.3,
  child: FloatingActionButton.large(
    onPressed: (){},
    tooltip: 'Start Engine',
    backgroundColor: Colors.transparent,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(50),
    ),
    child: Image.asset(
      'Assets/Images/Start Engine.png',
      width: screenWidth * 0.28,
      height: screenWidth * 0.28,
      fit: BoxFit.cover,
    ),
    elevation: 0.0,
  ),
),
bottomNavigationBar: BottomAppBar(
  elevation: 5,
  height: screenHeight * 0.08,
  padding: EdgeInsets.all(0),
  notchMargin: 0.0,
  shape: CircularNotchedRectangle(),
  child: ClipRRect(
    borderRadius: BorderRadius.only(
      topLeft: Radius.circular(5),
      topRight: Radius.circular(5),
    ),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Container(
          width: screenWidth / 3,
          decoration: BoxDecoration(
              color: const Color.fromRGBO(25, 192, 122, 1),
              border: Border(
                left: BorderSide(
                  color: Colors.black,
                  width: 1.0,
                ),
              )),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              SizedBox(
                height: screenHeight * 0.025,
                width: screenWidth * 0.04,
                child: IconButton(
                  icon: const Icon(
                    Icons.home,
                    size: 20,
                    color: Colors.white,
                  ),
                  padding: EdgeInsets.zero,
                  onPressed: () {
                    /*Navigator.push(context,
                        MaterialPageRoute(builder: (context) => ));*/
                  },
                ),
              ),
              SizedBox(height: 10),
              Text(
                'Home',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                  fontSize: 12,
                  fontFamily: 'default',
                ),
              ),
            ],
          ),
        ),
        Container(
          decoration: BoxDecoration(
            color: const Color.fromRGBO(25, 192, 122, 1),
            border: Border(
              left: BorderSide(
                color: Colors.black,
                width: 1.0,
              ),
            ),
          ),
          width: screenWidth / 3,
          height: screenHeight * 0.08,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Padding(
                padding: EdgeInsets.only(bottom: screenHeight * 0.01),
                child: Text(
                  'Start Engine',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                    fontSize: 12,
                    fontFamily: 'default',
                  ),
                ),
              ),
            ],
          ),
        ),
        Container(
          width: screenWidth / 3,
          decoration: BoxDecoration(
              color: const Color.fromRGBO(25, 192, 122, 1),
              border: Border(
                left: BorderSide(
                  color: Colors.black,
                  width: 1.0,
                ),
              )),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              SizedBox(
                height: screenHeight * 0.025,
                width: screenWidth * 0.04,
                child: IconButton(
                  icon: const Icon(
                    Icons.info,
                    size: 20,
                    color: Colors.white,
                  ),
                  padding: EdgeInsets.zero,
                  onPressed: () {
                    /*Navigator.push(context,
                        MaterialPageRoute(builder: (context) => ));*/
                  },
                ),
              ),
              SizedBox(height: 10),
              Text(
                'Information',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                  fontSize: 12,
                  fontFamily: 'default',
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  ),
),

进阶自定义FAB位置(可选)

如果需要更精准的FAB位置偏移,不要用Positioned,而是自定义FloatingActionButtonLocation:

class CustomCenterDockedLocation extends FloatingActionButtonLocation {
  const CustomCenterDockedLocation();

  @override
  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    final double fabX = scaffoldGeometry.scaffoldSize.width / 2 - scaffoldGeometry.floatingActionButtonSize.width / 2;
    // 调整Y轴偏移实现向上移动的效果,替代Positioned的bottom参数
    final double fabY = scaffoldGeometry.scaffoldSize.height - scaffoldGeometry.bottomSheetSize.height - scaffoldGeometry.bottomNavigationBarSize.height - scaffoldGeometry.floatingActionButtonSize.height + 20;
    return Offset(fabX, fabY);
  }
}

使用时替换为:

floatingActionButtonLocation: const CustomCenterDockedLocation(),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:20:15