import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:cs_resources/generated/assets.dart'; import 'package:cs_resources/constants/color_constants.dart'; import 'package:router/ext/auto_router_extensions.dart'; import 'my_load_image.dart'; import 'search_app_bar.dart'; class MyAppBar { ///封装的默认的AppBar,Light默认模式下,黑色图标+黑色文本,Dark模式下,白色图标+白色文本 static AppBar appBar(BuildContext context, String title, {void Function()? backCallback, String? backIconPath, double? backIconWidth, double? backIconHeight, String? subTitle, Color? subTitleColor, Color textColor = Colors.white, Color backgroundColor = Colors.transparent, SystemUiOverlayStyle? systemUiOverlayStyle, List? actions}) { return AppBar( //设置变色与背景颜色一致,避免滚动的时候AppBar变色 backgroundColor: backgroundColor, surfaceTintColor: backgroundColor, systemOverlayStyle: systemUiOverlayStyle, leading: IconButton( icon: MyAssetImage(backIconPath ?? Assets.baseLibWhiteBack, width: backIconWidth ?? 11, height: backIconHeight ?? 18), onPressed: () { if (backCallback != null) { backCallback(); } else { appRouter.maybePop(); } }, ), centerTitle: true, title: subTitle == null ? Text( title, style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), ) : Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( title, style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), ), Text( subTitle, style: TextStyle(color: subTitleColor ?? Colors.white, fontSize: 15, fontWeight: FontWeight.w400), ) ], ), actions: actions, elevation: 0.0, bottom: const PreferredSize( preferredSize: Size.fromHeight(0.5), child: Divider( height: 0.5, indent: 0.0, color: ColorConstants.dividerBar, )), ); } //自定义高度快 static SizedBox rowHeight({double height = 30}) { return SizedBox(height: height); } //自定义宽度快 static SizedBox rowWidth({double width = 30}) { return SizedBox(width: width); } /// 带搜索的AppBar static AppBar appSearchBar(BuildContext context, {void Function()? backCallback, String? value, String? hintText, Color textColor = Colors.white, Color backgroundColor = Colors.transparent, ValueChanged? onSearch, ValueChanged? onChanged, SystemUiOverlayStyle? systemUiOverlayStyle, TextEditingController? controller, List? actions}) { return AppBar( backgroundColor: backgroundColor, surfaceTintColor: backgroundColor, systemOverlayStyle: systemUiOverlayStyle, // 标题与其他控件的间隔 titleSpacing: 0, leading: IconButton( icon: const MyAssetImage(Assets.baseLibWhiteBack, width: 11, height: 18), onPressed: () { if (backCallback != null) { backCallback(); } else { appRouter.maybePop(); } }, ), centerTitle: true, title: SearchAppBar( onSearch: onSearch, onChanged: onChanged, value: value, hintText: hintText, controller: controller, ), actions: actions, elevation: 0.0, bottom: const PreferredSize( preferredSize: Size.fromHeight(0.5), child: Divider( height: 0.5, indent: 0.0, color: ColorConstants.dividerBar, )), ); } /// 当前App中的自定义TitleBar用于沉浸式处理,不是用在 Scaffold 下面的,直接放在 Column 下面即可 static Widget titleBar( BuildContext context, String title, { void Function()? backCallback, String? backIconPath, double? backIconWidth, double? backIconHeight, String? subTitle, Color? subTitleColor, bool needBottomDivider = true, Color textColor = Colors.white, Color backgroundColor = Colors.transparent, List? actions, }) { // 计算左侧和右侧固定容器的宽度 double sideWidth = 55; return Column( children: [ Container( height: kToolbarHeight, color: backgroundColor, child: Stack( children: [ // 返回图标在左侧 Positioned( left: 0, top: 0, bottom: 0, child: Container( width: sideWidth, alignment: Alignment.center, child: IconButton( icon: MyAssetImage( backIconPath ?? Assets.baseLibWhiteBack, width: backIconWidth ?? 11, height: backIconHeight ?? 18, ), onPressed: () { if (backCallback != null) { backCallback(); } else { appRouter.maybePop(); } }, ), ), ), // 标题在中间 Positioned.fill( child: Center( child: ConstrainedBox( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width - 2 * sideWidth, ), child: subTitle == null ? Text( title, style: TextStyle(color: textColor, fontSize: 18, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis, ) : Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( title, style: TextStyle(color: textColor, fontSize: 18, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis, ), Text( subTitle!, style: TextStyle(color: subTitleColor ?? textColor, fontSize: 15, fontWeight: FontWeight.w400), ), ], ), ), ), ), // 右侧的操作按钮 Positioned( right: 0, top: 0, bottom: 0, child: Container( alignment: Alignment.centerRight, child: Row( mainAxisSize: MainAxisSize.min, children: actions ?? [SizedBox(width: sideWidth)], ), ), ), ], ), ), // 底部的分割线 if (needBottomDivider) Divider( height: 0.5, color: ColorConstants.dividerBar, ), ], ); } /// 当前App中的自定义TitleBar用于沉浸式处理,不是用在 Scaffold 下面的,直接放在 Column 下面即可 static Widget searchTitleBar(BuildContext context, { void Function()? backCallback, String? value, String? hintText, Color textColor = Colors.white, Color backgroundColor = Colors.transparent, ValueChanged? onSearch, ValueChanged? onChanged, bool needBottomDivider = true, TextEditingController? controller, List? actions, }) { return Column( children: [ Container( height: kToolbarHeight, color: backgroundColor, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ // 返回图标 Container( width: 55, alignment: Alignment.center, child: IconButton( icon: MyAssetImage( Assets.baseLibWhiteBack, width: 11, height: 18, ), onPressed: () { if (backCallback != null) { backCallback(); } else { appRouter.maybePop(); } }, ), ), // 搜索栏 Expanded( child: SearchAppBar( onSearch: onSearch, onChanged: onChanged, value: value, hintText: hintText, controller: controller, ), ), // 右侧操作按钮 Container( alignment: Alignment.centerRight, child: Row( mainAxisSize: MainAxisSize.min, children: actions ?? [], ), ), ], ), ), // 底部的分割线 if (needBottomDivider) const Divider( height: 0.5, indent: 0.0, color: ColorConstants.dividerBar, ), ], ); } }