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

如何用Flutter CustomPainter实现指定样式的AppBar?

自定义曲线AppBar实现方案

下面是可直接复用的CustomPainter实现及配套自定义AppBar组件,你可以根据需求调整曲线形状:

1. 实现CustomPainter绘制曲线

class CurvedAppBarPainter extends CustomPainter {
  final Color color;
  final double curveHeight;

  CurvedAppBarPainter({required this.color, required this.curveHeight});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = color;
    final path = Path();

    // 构建路径:左上角 → 右上角 → 右下角 → 贝塞尔曲线到左下角 → 闭合
    path.moveTo(0, 0);
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height - curveHeight);
    
    // 二次贝塞尔曲线(中间凹入效果),可替换为三次贝塞尔实现更复杂形状
    path.quadraticBezierTo(
      size.width / 2,
      size.height,
      0,
      size.height - curveHeight,
    );

    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

2. 封装自定义AppBar组件

继承PreferredSizeWidget让它可以直接替换默认AppBar:

class CustomCurvedAppBar extends StatelessWidget implements PreferredSizeWidget {
  final String title;
  final Color backgroundColor;
  final double curveHeight;

  const CustomCurvedAppBar({
    super.key,
    required this.title,
    this.backgroundColor = Colors.blue,
    this.curveHeight = 30,
  });

  @override
  Widget build(BuildContext context) {
    final appBarHeight = preferredSize.height;
    return Stack(
      children: [
        // 绘制曲线背景的容器
        SizedBox(
          height: appBarHeight + curveHeight,
          child: CustomPaint(
            painter: CurvedAppBarPainter(
              color: backgroundColor,
              curveHeight: curveHeight,
            ),
          ),
        ),
        // 叠加原生AppBar(透明背景)
        Positioned(
          top: MediaQuery.of(context).padding.top,
          left: 0,
          right: 0,
          child: SizedBox(
            height: appBarHeight,
            child: AppBar(
              backgroundColor: Colors.transparent,
              elevation: 0,
              title: Text(title),
              centerTitle: true,
              // 可添加leading、actions等原生AppBar属性
            ),
          ),
        ),
      ],
    );
  }

  @override
  Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

3. 使用示例

Scaffold(
  appBar: CustomCurvedAppBar(
    title: "我的自定义AppBar",
    backgroundColor: Colors.deepPurple,
    curveHeight: 40, // 调整这个值改变曲线幅度
  ),
  body: const Center(child: Text("页面内容")),
)

调整曲线形状的技巧

  • 如果需要更复杂的曲线,把quadraticBezierTo换成cubicTo,通过两个控制点微调形状:
    path.cubicTo(
      size.width * 0.3, size.height - curveHeight, // 第一个控制点
      size.width * 0.7, size.height, // 第二个控制点
      0, size.height - curveHeight, // 终点
    );
    
  • 改变curveHeight的数值可以控制曲线的凸起/凹陷程度
  • 若要修改曲线位置(比如偏左/偏右),调整贝塞尔曲线的控制点x坐标即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:57:42