如何在Flutter中使用CustomPainter设计指定形状的AppBar
实现自定义弧形AppBar的解决方案
针对你遇到的问题,直接嵌套原生AppBar会受限于其内部布局约束(leading区域宽度固定、title区域起始位置受限),更灵活的方式是直接基于PreferredSizeWidget构建完整的自定义AppBar,通过分层布局实现设计效果:
完整代码实现
1. 自定义AppBar组件
import 'package:flutter/material.dart'; class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { final String title; const CustomAppBar({super.key, required this.title}); @override Widget build(BuildContext context) { return SizedBox( height: preferredSize.height, child: Stack( children: [ // 背景层:绘制左侧弧形背景 Positioned.fill( child: CustomPaint( painter: _AppBarBackgroundPainter(), ), ), // 内容层:返回按钮 Align( alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.only(left: 16), child: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.white), onPressed: () => Navigator.pop(context), ), ), ), // 内容层:标题文本 Align( alignment: Alignment.center, child: Text( title, style: const TextStyle( color: Colors.black, fontSize: 18, fontWeight: FontWeight.w600, ), ), ), ], ), ); } @override Size get preferredSize => const Size.fromHeight(kToolbarHeight + 10); }
2. 背景形状绘制器
class _AppBarBackgroundPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint()..color = const Color(0xff55847A); // 构建弧形路径,适配AppBar尺寸 final path = Path(); path.moveTo(0, size.height); // 起点:左下角 path.lineTo(0, 0); // 到左上角 // 二次贝塞尔曲线构建弧形,可根据设计图调整控制点坐标 path.quadraticBezierTo( size.width * 0.3, 0, size.width * 0.45, size.height * 0.5, ); path.quadraticBezierTo( size.width * 0.6, size.height, size.width, size.height, ); path.lineTo(size.width, size.height); // 回到右下角 path.close(); // 闭合路径 canvas.drawPath(path, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }
3. 使用方式
在Scaffold中直接引用:
Scaffold( appBar: CustomAppBar(title: "Dashboard"), body: const Center(child: Text("页面内容")), );
关键问题说明
为什么不用原生AppBar嵌套?
原生AppBar的leading区域有固定宽度限制(默认最大56px),无法容纳超出范围的自定义形状;title区域从leading之后开始布局,无法将形状对齐到AppBar最左侧。直接基于PreferredSizeWidget构建容器,用Stack分层布局,完全摆脱原生布局约束。CustomPainter参数解析
Canvas:绘制操作的画布,所有图形都绘制在这个画布上Size:当前CustomPaint组件的尺寸,这里对应AppBar的宽高,用相对比例(如size.width * 0.3)计算坐标,可适配不同屏幕Path:用于构建复杂自定义形状,quadraticBezierTo通过两个控制点调整弧形弧度,你可以修改控制点的数值来匹配设计图的弧形效果Paint:设置画笔颜色、填充/描边样式等属性
内容的提问来源于stack exchange,提问作者Sibghat ullah
相关产品推荐
相关产品推荐

