效果图
AppBar 详解
AppBar({
Key key,
this.leading, //widget类型,即可任意设计样式,表示左侧leading区域,通常为icon,如返回icon
this.automaticallyImplyLeading = true, // 如果leading!=null,该属性不生效;如果leading==null且为true,左侧leading区域留白;如果leading==null且为false,左侧leading区域扩展给title区域使用
this.title,//widget类型,即可任意设计样式,表示中间title区域,通常为标题栏
this.actions,// List<Widget>类型,即可任意设计样式,表示右侧actions区域,可放置多个widget,通常为icon,如搜索icon、菜单icon
this.flexibleSpace,
this.bottom, //PreferredSizeWidget类型,appbar底部区域,通常为Tab控件
this.elevation, //阴影高度,默认为4
this.shape,//ShapeBorder 类型,表示描边形状
this.backgroundColor, //Color类型,背景色
this.brightness,//Brightness类型,表示当前appbar主题是亮或暗色调,有dark和light两个值,可影响系统状态栏的图标颜色
this.iconTheme, //IconThemeData类型,可影响包括leading、title、actions中icon的颜色、透明度,及leading中的icon大小。
this.actionsIconTheme,
this.textTheme,// TextTheme类型,文本主题样式,可设置appbar中文本的许多样式,如字体大小、颜色、前景色、背景色等...
this.primary = true,//true时,appBar会以系统状态栏高度为间距显示在下方;false时,会和状态栏重叠,相当于全屏显示。
this.centerTitle, // boolean 类型,表示标题是否居中显示
this.titleSpacing = NavigationToolbar.kMiddleSpacing,//title区域水平方向与leading和actions的间距(padding)
this.toolbarOpacity = 1.0,//toolbar区域透明度
this.bottomOpacity = 1.0,//bottom区域透明度
}
代码实现
比较简单,直接上代码
import 'package:flutter/material.dart';
const double _elevation = 0;
const double _titleFontSize = 18.0;
const double _textFontSize = 16.0;
const double _itemSpace = 15.0; // 右侧item内间距
const double _imgWH = 22.0; // 右侧图片宽高
const double _rightSpace = 5.0; // 右侧item右间距
// 默认颜色
const Color _bgColor = Color(0xFF3BB815);
const Color _bgDarkColor = Color(0xFF0A0A0A);
const Color _titleColor = Colors.white;
// 状态栏字体颜色,当backgroundColor透明或者是白色,状态栏字体为黑色,暗黑模式为白色
const Brightness _brightness = Brightness.light;
/// 导航条基类
class BaseAppBar extends StatefulWidget implements PreferredSizeWidget {
const BaseAppBar(
this.title, {
Key? key,
this.rightText,
this.rightImgPath,
this.leftWidget,
this.titleWidget,
this.rightWidgets,
this.bgColor,
this.brightness = _brightness,
this.elevation: _elevation,
this.bottomWidget,
this.flexibleSpace,
this.leftItemCallBack,
this.rightItemCallBack,
}) : super(key: key);
final String title; // 标题文字
final String? rightText; // 右侧按钮文字
final String? rightImgPath; // 右侧按钮图片路径,优先级高于rightText
final Widget? leftWidget; // 左侧Widget,为空显示返回按钮
final Widget? titleWidget; // 标题Widget,优先级高于title
final List<Widget>? rightWidgets; // 优先级高于rightText和rightImgPath
final Color? bgColor; // 背景颜色,默认主题色,设置的颜色优先级高于暗黑模式
final Brightness brightness;
final double elevation;
final PreferredSizeWidget? bottomWidget;
final Widget? flexibleSpace;
final Function? leftItemCallBack;
final Function? rightItemCallBack;
@override
State<BaseAppBar> createState() => _BaseAppBarState();
@override
Size get preferredSize => Size.fromHeight(
kToolbarHeight + (bottomWidget?.preferredSize.height ?? 0.0));
}
class _BaseAppBarState extends State<BaseAppBar> {
@override
Widget build(BuildContext context) {
return _appBar();
}
Widget _appBar() {
// 默认颜色
Color titleAndIconColor = _titleColor;
Color bgColor = widget.bgColor ?? _bgColor;
var brightness = widget.brightness;
// 如果背景透明或者是白色,设置字体和图标、状态栏字体为黑色
// if (widget.bgColor == Colors.transparent ||
// widget.bgColor == Colors.white ||
// widget.bgColor == KColors.kNavWhiteBgColor) {
// titleAndIconColor = Colors.black;
// brightness = Brightness.dark;
// } else {
// brightness = Brightness.light;
// }
// TODO: 通过ThemeProvider进行主题管理
// final provider = Provider.of<ThemeProvider>(context);
// final bool isDark = context.jhIsDark;
// // 设置的颜色优先级高于暗黑模式
// bgColor = widget.bgColor ?? (isDark ? _bgDarkColor : provider.getThemeColor());
// if (isDark) {
titleAndIconColor = _titleColor;
// }
// 标题
var titleWidget = widget.titleWidget ??
Text(widget.title,
style:
TextStyle(fontSize: _titleFontSize, color: titleAndIconColor),
maxLines: 2);
// 左侧
var backWidget = IconButton(
// icon: Icon(Icons.arrow_back_ios,color: _color),
icon: ImageIcon(
AssetImage('assets/images/common/ic_nav_back_white.png'),
color: titleAndIconColor,
),
iconSize: 18,
padding: const EdgeInsets.fromLTRB(0, 0, 10, 0),
onPressed: () {
if (widget.leftItemCallBack == null) {
_popThis(context);
} else {
widget.leftItemCallBack!();
}
},
);
var leftWidget = widget.leftWidget ?? backWidget;
// 右侧
Widget rightWidget = Text('');
if (widget.rightText != null) {
rightWidget = InkWell(
child: Container(
margin: EdgeInsets.all(_itemSpace),
color: Colors.transparent,
child: Center(
child: Text(widget.rightText!,
style: TextStyle(
fontSize: _textFontSize, color: titleAndIconColor)),
),
),
onTap: () => widget.rightItemCallBack?.call(),
);
}
if (widget.rightImgPath != null) {
rightWidget = IconButton(
icon: Image.asset(widget.rightImgPath!,
width: _imgWH, height: _imgWH, color: titleAndIconColor),
onPressed: () => widget.rightItemCallBack?.call(),
);
}
var actions = [
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[rightWidget, SizedBox(width: _rightSpace)],
),
];
var rightWidgets = widget.rightWidgets ?? actions;
return AppBar(
title: titleWidget,
centerTitle: true,
backgroundColor: bgColor,
// systemOverlayStyle: JhStatusBarUtils.getStatusBarStyle(isDark: isDark, brightness: brightness),
bottom: widget.bottomWidget,
elevation: widget.elevation,
leading: leftWidget,
actions: rightWidgets,
flexibleSpace: widget.flexibleSpace,
);
}
}
void _popThis(BuildContext context) {
if (Navigator.of(context).canPop()) {
FocusManager.instance.primaryFocus?.unfocus();
Navigator.of(context).pop();
}
}