my_appbar.dart 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. import 'package:flutter/widgets.dart';
  5. import 'package:cs_resources/generated/assets.dart';
  6. import 'package:cs_resources/constants/color_constants.dart';
  7. import 'my_load_image.dart';
  8. import 'search_app_bar.dart';
  9. class MyAppBar {
  10. ///封装的默认的AppBar,Light默认模式下,黑色图标+黑色文本,Dark模式下,白色图标+白色文本
  11. static AppBar appBar(BuildContext context, String title,
  12. {void Function()? backCallback,
  13. String? backIconPath,
  14. double? backIconWidth,
  15. double? backIconHeight,
  16. String? subTitle,
  17. Color? subTitleColor,
  18. Color textColor = Colors.white,
  19. Color backgroundColor = Colors.transparent,
  20. SystemUiOverlayStyle? systemUiOverlayStyle,
  21. List<Widget>? actions}) {
  22. return AppBar(
  23. //设置变色与背景颜色一致,避免滚动的时候AppBar变色
  24. backgroundColor: backgroundColor,
  25. surfaceTintColor: backgroundColor,
  26. systemOverlayStyle: systemUiOverlayStyle,
  27. leading: IconButton(
  28. icon: MyAssetImage(backIconPath ?? "Assets.baseLibWhiteBack", width: backIconWidth ?? 11, height: backIconHeight ?? 18),
  29. onPressed: () {
  30. if (backCallback != null) {
  31. backCallback();
  32. } else {
  33. Navigator.pop(context);
  34. }
  35. },
  36. ),
  37. centerTitle: true,
  38. title: subTitle == null
  39. ? Text(
  40. title,
  41. style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500),
  42. )
  43. : Column(
  44. mainAxisSize: MainAxisSize.max,
  45. mainAxisAlignment: MainAxisAlignment.center,
  46. crossAxisAlignment: CrossAxisAlignment.center,
  47. children: [
  48. Text(
  49. title,
  50. style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500),
  51. ),
  52. Text(
  53. subTitle,
  54. style: TextStyle(color: subTitleColor ?? Colors.white, fontSize: 15, fontWeight: FontWeight.w400),
  55. )
  56. ],
  57. ),
  58. actions: actions,
  59. elevation: 0.0,
  60. bottom: const PreferredSize(
  61. preferredSize: Size.fromHeight(0.5),
  62. child: Divider(
  63. height: 0.5,
  64. indent: 0.0,
  65. color: ColorConstants.dividerBar,
  66. )),
  67. );
  68. }
  69. //自定义高度快
  70. static SizedBox rowHeight({double height = 30}) {
  71. return SizedBox(height: height);
  72. }
  73. //自定义宽度快
  74. static SizedBox rowWidth({double width = 30}) {
  75. return SizedBox(width: width);
  76. }
  77. /// 带搜索的AppBar
  78. static AppBar appSearchBar(BuildContext context,
  79. {void Function()? backCallback,
  80. String? value,
  81. String? hintText,
  82. Color textColor = Colors.white,
  83. Color backgroundColor = Colors.transparent,
  84. ValueChanged<String>? onSearch,
  85. ValueChanged<String>? onChanged,
  86. SystemUiOverlayStyle? systemUiOverlayStyle,
  87. TextEditingController? controller,
  88. List<Widget>? actions}) {
  89. return AppBar(
  90. backgroundColor: backgroundColor,
  91. surfaceTintColor: backgroundColor,
  92. systemOverlayStyle: systemUiOverlayStyle,
  93. // 标题与其他控件的间隔
  94. titleSpacing: 0,
  95. leading: IconButton(
  96. icon: const MyAssetImage("Assets.baseLibWhiteBack", width: 11, height: 18),
  97. onPressed: () {
  98. if (backCallback != null) {
  99. backCallback();
  100. } else {
  101. Navigator.pop(context);
  102. }
  103. },
  104. ),
  105. centerTitle: true,
  106. title: SearchAppBar(
  107. onSearch: onSearch,
  108. onChanged: onChanged,
  109. value: value,
  110. hintText: hintText,
  111. controller: controller,
  112. ),
  113. actions: actions,
  114. elevation: 0.0,
  115. bottom: const PreferredSize(
  116. preferredSize: Size.fromHeight(0.5),
  117. child: Divider(
  118. height: 0.5,
  119. indent: 0.0,
  120. color: ColorConstants.dividerBar,
  121. )),
  122. );
  123. }
  124. /// 当前App中的自定义TitleBar用于沉浸式处理,不是用在 Scaffold 下面的,直接放在 Column 下面即可
  125. static Widget titleBar(
  126. BuildContext context,
  127. String title, {
  128. void Function()? backCallback,
  129. String? backIconPath,
  130. double? backIconWidth,
  131. double? backIconHeight,
  132. String? subTitle,
  133. Color? subTitleColor,
  134. bool needBottomDivider = true,
  135. Color textColor = Colors.white,
  136. Color backgroundColor = Colors.transparent,
  137. List<Widget>? actions,
  138. }) {
  139. // 计算左侧和右侧固定容器的宽度
  140. double sideWidth = 55;
  141. return Column(
  142. children: [
  143. Container(
  144. height: kToolbarHeight,
  145. color: backgroundColor,
  146. child: Stack(
  147. children: [
  148. // 返回图标在左侧
  149. Positioned(
  150. left: 0,
  151. top: 0,
  152. bottom: 0,
  153. child: Container(
  154. width: sideWidth,
  155. alignment: Alignment.center,
  156. child: IconButton(
  157. icon: MyAssetImage(
  158. backIconPath ?? "Assets.baseLibWhiteBack",
  159. width: backIconWidth ?? 11,
  160. height: backIconHeight ?? 18,
  161. ),
  162. onPressed: () {
  163. if (backCallback != null) {
  164. backCallback();
  165. } else {
  166. Navigator.pop(context);
  167. }
  168. },
  169. ),
  170. ),
  171. ),
  172. // 标题在中间
  173. Positioned.fill(
  174. child: Center(
  175. child: ConstrainedBox(
  176. constraints: BoxConstraints(
  177. maxWidth: MediaQuery.of(context).size.width - 2 * sideWidth,
  178. ),
  179. child: subTitle == null
  180. ? Text(
  181. title,
  182. style: TextStyle(color: textColor, fontSize: 18, fontWeight: FontWeight.w500),
  183. overflow: TextOverflow.ellipsis,
  184. )
  185. : Column(
  186. mainAxisSize: MainAxisSize.min,
  187. mainAxisAlignment: MainAxisAlignment.center,
  188. crossAxisAlignment: CrossAxisAlignment.center,
  189. children: [
  190. Text(
  191. title,
  192. style: TextStyle(color: textColor, fontSize: 18, fontWeight: FontWeight.w500),
  193. overflow: TextOverflow.ellipsis,
  194. ),
  195. Text(
  196. subTitle!,
  197. style: TextStyle(color: subTitleColor ?? textColor, fontSize: 15, fontWeight: FontWeight.w400),
  198. ),
  199. ],
  200. ),
  201. ),
  202. ),
  203. ),
  204. // 右侧的操作按钮
  205. Positioned(
  206. right: 0,
  207. top: 0,
  208. bottom: 0,
  209. child: Container(
  210. alignment: Alignment.centerRight,
  211. child: Row(
  212. mainAxisSize: MainAxisSize.min,
  213. children: actions ?? [SizedBox(width: sideWidth)],
  214. ),
  215. ),
  216. ),
  217. ],
  218. ),
  219. ),
  220. // 底部的分割线
  221. if (needBottomDivider)
  222. Divider(
  223. height: 0.5,
  224. color: ColorConstants.dividerBar,
  225. ),
  226. ],
  227. );
  228. }
  229. /// 当前App中的自定义TitleBar用于沉浸式处理,不是用在 Scaffold 下面的,直接放在 Column 下面即可
  230. static Widget searchTitleBar(BuildContext context, {
  231. void Function()? backCallback,
  232. String? value,
  233. String? hintText,
  234. Color textColor = Colors.white,
  235. Color backgroundColor = Colors.transparent,
  236. ValueChanged<String>? onSearch,
  237. ValueChanged<String>? onChanged,
  238. bool needBottomDivider = true,
  239. TextEditingController? controller,
  240. List<Widget>? actions,
  241. }) {
  242. return Column(
  243. children: [
  244. Container(
  245. height: kToolbarHeight,
  246. color: backgroundColor,
  247. child: Row(
  248. crossAxisAlignment: CrossAxisAlignment.center,
  249. children: [
  250. // 返回图标
  251. Container(
  252. width: 55,
  253. alignment: Alignment.center,
  254. child: IconButton(
  255. icon: MyAssetImage(
  256. "Assets.baseLibWhiteBack",
  257. width: 11,
  258. height: 18,
  259. ),
  260. onPressed: () {
  261. if (backCallback != null) {
  262. backCallback();
  263. } else {
  264. Navigator.pop(context);
  265. }
  266. },
  267. ),
  268. ),
  269. // 搜索栏
  270. Expanded(
  271. child: SearchAppBar(
  272. onSearch: onSearch,
  273. onChanged: onChanged,
  274. value: value,
  275. hintText: hintText,
  276. controller: controller,
  277. ),
  278. ),
  279. // 右侧操作按钮
  280. Container(
  281. alignment: Alignment.centerRight,
  282. child: Row(
  283. mainAxisSize: MainAxisSize.min,
  284. children: actions ?? [],
  285. ),
  286. ),
  287. ],
  288. ),
  289. ),
  290. // 底部的分割线
  291. if (needBottomDivider)
  292. const Divider(
  293. height: 0.5,
  294. indent: 0.0,
  295. color: ColorConstants.dividerBar,
  296. ),
  297. ],
  298. );
  299. }
  300. }