目前Flutter官方提供的AppBar很是强大放在国外应该够用,但是放在国内肯定如下图


Scaffold(
appBar: AppBar(
title: const Text('标题'),
leading: Row(
children: <Widget>[Icon(Icons.keyboard_arrow_left), Text("广州")],
),
),
);
一运行

if (leading != null) {
leading = ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: _kLeadingWidth),
child: leading,
);
}
const double _kLeadingWidth = kToolbarHeight; // So the leading button is square.
可以说应为Google遵循Material风格把这个宽度写死了。
接下来我们分析一下AppBar的页面源码
class AppBar extends StatefulWidget implements PreferredSizeWidget {
...
@override
Widget build(BuildContext context) {
...
return Semantics(
container: true,
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: overlayStyle,
child: Material(
color: widget.backgroundColor
?? appBarTheme.color
?? theme.primaryColor,
elevation: widget.elevation
?? appBarTheme.elevation
?? _defaultElevation,
shape: widget.shape,
child: Semantics(
explicitChildNodes: true,
child: appBar,
),
),
),
);
}
}
如上图我忽略一些暂时我们用不到的代码,这样一看其实就跟我们写的普通页面一模一样只是其中多了一些Semantics语义标签,Semantics语义标签这里先不做讲解。那么根据上面的图我们先建一个AppTitleBar的去实现PreferredSizeWidget
class AppTitleBar extends StatefulWidget implements PreferredSizeWidget {
@override
_AppTitleBarState createState() => _AppTitleBarState();
@override
// TODO: implement preferredSize
Size get preferredSize => null;
}
class _AppTitleBarState extends State<AppTitleBar> {
@override
Widget build(BuildContext context) {
return Container();
}
}
preferredSize代表着限制子widget的大小,我们现在就拿着这个preferredSize回到AppBar里面搜索一下发现了这一句
preferredSize = Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
当bottom没有值传进来的时候直接就拿了kToolbarHeight,我们再点击进kToolbarHeight里面
/// The height of the toolbar component of the [AppBar].
const double kToolbarHeight = 56.0;
发现这就是一个写死的导航栏高度,那这就好办了
class AppTitleBar extends StatefulWidget implements PreferredSizeWidget {
@override
_AppTitleBarState createState() => _AppTitleBarState();
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
class _AppTitleBarState extends State<AppTitleBar> {
@override
Widget build(BuildContext context) {
return Container(color: Colors.red, child: Text("我是标题"), height: double.infinity);
}
}
现在我们就完成了一个简易的AppBar,来运行一下

// The padding applies to the toolbar and tabbar, not the flexible space.
if (widget.primary) {
appBar = SafeArea(
top: true,
child: appBar,
);
}
只要我们把SafeArea套上去就ok了,接下来就是同志们自己根据喜好自定义AppBar咯