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

如何在Flutter中实现底部导航栏的曲线效果?

Flutter 带曲线效果的底部导航栏实现方案

下面给你两种适配需求的实现方式,都是基于原生组件扩展,不用依赖第三方包:

方法一:全局曲线裁剪的底部导航栏

适合整个导航栏底部带曲线的场景,用ClipPath自定义裁剪路径即可:

  1. 先写一个自定义裁剪器,定义曲线形状:
class CurveBottomClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    // 从左下角开始绘制路径
    path.lineTo(0, size.height);
    // 左侧直线到曲线起点
    path.lineTo(size.width * 0.3, size.height);
    // 绘制中间向上凸起的贝塞尔曲线
    path.quadraticBezierTo(
      size.width * 0.5, // 曲线控制点X
      size.height - 30, // 曲线控制点Y(数值越大,凸起越高)
      size.width * 0.7, // 曲线终点X
      size.height, // 曲线终点Y
    );
    // 右侧直线到右下角
    path.lineTo(size.width, size.height);
    path.lineTo(size.width, 0);
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
  1. 把底部导航栏套在ClipPath里使用:
ClipPath(
  clipper: CurveBottomClipper(),
  child: Container(
    height: 60,
    color: Colors.white,
    child: BottomNavigationBar(
      elevation: 0, // 去掉默认阴影,避免和曲线冲突
      backgroundColor: Colors.transparent,
      items: const [
        BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
        BottomNavigationBarItem(icon: Icon(Icons.search), label: '搜索'),
        BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
      ],
    ),
  ),
)

方法二:选中项凸起的曲线导航栏

如果是指定某个Tab(比如中间的发布按钮)有单独的凸起曲线,用Stack叠加层来实现:

  1. 自定义绘制曲线的Painter:
class CurvePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = Colors.blue; // 曲线颜色和导航栏区分开
    final path = Path();
    // 绘制向上凸起的圆弧曲线
    path.moveTo(0, 0);
    path.quadraticBezierTo(
      size.width / 2,
      -20, // 凸起高度,负数表示向上凸
      size.width,
      0,
    );
    // 闭合路径,形成一个带曲线的色块
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height);
    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}
  1. 用Stack组合导航栏、背景和曲线:
int _selectedIndex = 1; // 默认选中中间项

Stack(
  alignment: Alignment.bottomCenter,
  children: [
    // 导航栏基础背景
    Container(
      height: 60,
      color: Colors.white,
    ),
    // 选中项的曲线装饰,根据选中位置动态调整
    Positioned(
      bottom: 0,
      left: MediaQuery.of(context).size.width / 2 - 40, // 居中放置,宽度80
      child: CustomPaint(
        size: const Size(80, 30),
        painter: CurvePainter(),
      ),
    ),
    // 底部导航栏,背景设为透明
    BottomNavigationBar(
      elevation: 0,
      backgroundColor: Colors.transparent,
      currentIndex: _selectedIndex,
      onTap: (index) {
        setState(() {
          _selectedIndex = index;
        });
      },
      items: const [
        BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
        BottomNavigationBarItem(icon: Icon(Icons.add_circle), label: '发布'),
        BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
      ],
    ),
  ],
)

调整技巧

  • 曲线弧度:修改quadraticBezierTo的控制点坐标,就能调整曲线的弯曲程度和凸起高度。
  • 适配屏幕:尽量用比例值(比如size.width * 0.5)代替固定像素,避免不同屏幕上变形。
  • 阴影效果:可以给曲线容器加BoxShadow,或者在CustomPaint里多画一层灰色的阴影路径,增强立体感。

内容的提问来源于stack exchange,提问作者Tarek mohamed Hassain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:05:16