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 'package:widgets/ext/ex_widget.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 backgroundColor = Colors.transparent, SystemUiOverlayStyle? systemUiOverlayStyle, bool showBottomDivider = false, List? actions}) { // 检查当前主题是亮色还是暗色 final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; return AppBar( //设置变色与背景颜色一致,避免滚动的时候AppBar变色 backgroundColor: backgroundColor, surfaceTintColor: backgroundColor, systemOverlayStyle: systemUiOverlayStyle, // 如果没有自带的返回按钮,直接使用系统自带的返回图标 leading: backIconPath != null ? IconButton( icon: MyAssetImage( backIconPath, width: backIconWidth ?? 11, height: backIconHeight ?? 18, ), onPressed: backCallback, ) : null, iconTheme: IconThemeData(color: isDarkMode ? Colors.white : Theme.of(context).colorScheme.primary), centerTitle: true, title: subTitle == null ? Text( title, style: TextStyle(color: isDarkMode ? Colors.white : Colors.black, fontSize: 17, fontWeight: FontWeight.w500), ) : Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( title, style: TextStyle(color: isDarkMode ? Colors.white : Colors.black, fontSize: 17, fontWeight: FontWeight.w500), ), Text( subTitle, style: TextStyle(color: isDarkMode ? Colors.white : Colors.black, fontSize: 15, fontWeight: FontWeight.w400), ) ], ), actions: actions, elevation: 0.0, bottom: showBottomDivider // 根据变量控制 bottom 的显示 ? const PreferredSize( preferredSize: Size.fromHeight(0.5), child: Divider( height: 0.5, indent: 0.0, color: ColorConstants.dividerBar, )) : null, ); } /// 带搜索的AppBar static AppBar searchAppBar(BuildContext context, {void Function()? backCallback, String? value, String? hintText, String? backIconPath, double? backIconWidth, double? backIconHeight, Color textColor = Colors.black, Color backgroundColor = Colors.transparent, ValueChanged? onSearch, ValueChanged? onChanged, SystemUiOverlayStyle? systemUiOverlayStyle, TextEditingController? controller, bool showBottomDivider = false, List? actions}) { // 检查当前主题是亮色还是暗色 final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; return AppBar( backgroundColor: backgroundColor, surfaceTintColor: backgroundColor, systemOverlayStyle: systemUiOverlayStyle, // 标题与其他控件的间隔 titleSpacing: 0, // 如果没有自带的返回按钮,直接使用系统自带的返回图标 leading: backIconPath != null ? IconButton( icon: MyAssetImage( backIconPath, width: backIconWidth ?? 11, height: backIconHeight ?? 18, ), onPressed: backCallback, ) : null, iconTheme: IconThemeData(color: isDarkMode ? Colors.white : Theme.of(context).colorScheme.primary), centerTitle: true, title: SearchAppBar( onSearch: onSearch, onChanged: onChanged, value: value, hintText: hintText, controller: controller, ), actions: actions, elevation: 0.0, bottom: showBottomDivider // 根据变量控制 bottom 的显示 ? const PreferredSize( preferredSize: Size.fromHeight(0.5), child: Divider( height: 0.5, indent: 0.0, color: ColorConstants.dividerBar, )) : null, ); } /// 当前App中的自定义TitleBar用于沉浸式处理,不是用在 Scaffold 下面的,直接放在 Column 下面即可 static Widget titleBar( BuildContext context, String title, { void Function()? backCallback, String? backIconPath, double? backIconWidth, double? backIconHeight, String? subTitle, Color backgroundColor = Colors.transparent, bool showBottomDivider = false, List? actions, }) { // 计算左侧和右侧固定容器的宽度 double sideWidth = 55; // 检查当前主题是亮色还是暗色 final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; 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: backIconPath != null ? IconButton( icon: MyAssetImage( backIconPath, width: backIconWidth ?? 11, height: backIconHeight ?? 18, ), onPressed: () { if (backCallback != null) { backCallback(); } else { appRouter.maybePop(); } }, ) : BackButton( color: isDarkMode ? Colors.white : Theme.of(context).colorScheme.primary, 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: isDarkMode ? Colors.white : Colors.black, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis, ) : Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( title, style: TextStyle(color: isDarkMode ? Colors.white : Colors.black, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis, ), Text( subTitle, style: TextStyle(color: isDarkMode ? Colors.white : Colors.black, 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 (showBottomDivider) const Divider( height: 0.5, color: ColorConstants.dividerBar, ), ], ); } /// 当前App中的自定义TitleBar用于沉浸式处理,不是用在 Scaffold 下面的,直接放在 Column 下面即可 static Widget searchTitleBar( BuildContext context, { void Function()? backCallback, String? value, String? hintText, String? backIconPath, double? backIconWidth, double? backIconHeight, Color backgroundColor = Colors.transparent, ValueChanged? onSearch, ValueChanged? onChanged, TextEditingController? controller, bool showBottomDivider = false, List? actions, }) { // 检查当前主题是亮色还是暗色 final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; return Column( children: [ Container( height: kToolbarHeight, color: backgroundColor, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ // 返回图标 Container( width: 55, alignment: Alignment.center, child: backIconPath != null ? IconButton( icon: MyAssetImage( backIconPath, width: backIconWidth ?? 11, height: backIconHeight ?? 18, ), onPressed: () { if (backCallback != null) { backCallback(); } else { appRouter.maybePop(); } }, ) : BackButton( color: isDarkMode ? Colors.white : Theme.of(context).colorScheme.primary, 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 (showBottomDivider) const Divider( height: 0.5, indent: 0.0, color: ColorConstants.dividerBar, ), ], ); } }