search_app_bar.dart 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
  3. import 'package:get/get.dart';
  4. import 'package:cs_resources/generated/assets.dart';
  5. import 'package:widgets/ext/ex_widget.dart';
  6. import '../utils/dark_theme_util.dart';
  7. import 'my_load_image.dart';
  8. import 'package:cs_resources/constants/color_constants.dart';
  9. class SearchAppBar extends StatefulWidget {
  10. SearchAppBar({
  11. Key? key,
  12. // this.backPath,
  13. this.borderRadius = 5,
  14. this.autoFocus = false,
  15. this.focusNode,
  16. this.controller,
  17. this.height = 35,
  18. this.value,
  19. // this.leading,
  20. this.backgroundColor,
  21. this.suffix,
  22. this.actions = const [],
  23. this.hintText,
  24. this.onTap,
  25. this.onClear,
  26. this.onCancel,
  27. this.onChanged,
  28. this.onSearch,
  29. // this.onRightTap,
  30. }) : super(key: key);
  31. final double? borderRadius;
  32. final bool? autoFocus;
  33. final FocusNode? focusNode;
  34. final TextEditingController? controller;
  35. // 输入框高度 默认35
  36. final double height;
  37. // 默认值
  38. final String? value;
  39. //配置暗黑模式
  40. // final String? backPath;
  41. // 最前面的组件
  42. // final Widget? leading;
  43. // 背景色
  44. final Color? backgroundColor;
  45. // 搜索框内部后缀组件
  46. final Widget? suffix;
  47. // 搜索框右侧组件
  48. final List<Widget> actions;
  49. // 输入框提示文字
  50. final String? hintText;
  51. // 输入框点击回调
  52. final VoidCallback? onTap;
  53. // 清除输入框内容回调
  54. final VoidCallback? onClear;
  55. // 清除输入框内容并取消输入
  56. final VoidCallback? onCancel;
  57. // 输入框内容改变
  58. final ValueChanged<String>? onChanged;
  59. // 点击键盘搜索
  60. final ValueChanged<String>? onSearch;
  61. // 点击右边widget
  62. // final VoidCallback? onRightTap;
  63. @override
  64. _SearchAppBarState createState() => _SearchAppBarState();
  65. }
  66. class _SearchAppBarState extends State<SearchAppBar> {
  67. TextEditingController? _controller;
  68. FocusNode? _focusNode;
  69. bool get isFocus => _focusNode?.hasFocus ?? false; //是否获取焦点
  70. bool get isTextEmpty => _controller?.text.isEmpty ?? false; //输入框是否为空
  71. bool get isActionEmpty => widget.actions.isEmpty; // 右边布局是否为空
  72. bool isShowCancel = false;
  73. @override
  74. void initState() {
  75. _controller = widget.controller ?? TextEditingController();
  76. _focusNode = widget.focusNode ?? FocusNode();
  77. if (widget.value != null) _controller?.text = widget.value ?? "";
  78. // 焦点获取失去监听
  79. _focusNode?.addListener(() => setState(() {}));
  80. // 文本输入监听
  81. _controller?.addListener(() {
  82. setState(() {});
  83. });
  84. super.initState();
  85. }
  86. // 清除输入框内容
  87. void _onClearInput() {
  88. setState(() {
  89. _controller?.clear();
  90. });
  91. widget.onClear?.call();
  92. }
  93. // 取消输入框编辑失去焦点
  94. void _onCancelInput() {
  95. setState(() {
  96. _controller?.clear();
  97. _focusNode?.unfocus(); //失去焦点
  98. });
  99. // 执行onCancel
  100. widget.onCancel?.call();
  101. }
  102. Widget _suffix() {
  103. if (!isTextEmpty) {
  104. return InkWell(
  105. onTap: _onClearInput,
  106. child: SizedBox(
  107. width: widget.height,
  108. height: widget.height,
  109. child: Icon(Icons.cancel, size: 22, color: DarkThemeUtil.multiColors(const Color(0xFF999999), darkColor: Colors.white)),
  110. ),
  111. );
  112. }
  113. return widget.suffix ?? SizedBox();
  114. }
  115. List<Widget> _actions() {
  116. List<Widget> list = [];
  117. // if (isFocus || !isTextEmpty) {
  118. // list.add(InkWell(
  119. // onTap: widget.onRightTap ?? _onCancelInput,
  120. // child: Container(
  121. // constraints: BoxConstraints(minWidth: 48.w),
  122. // alignment: Alignment.center,
  123. // child: MyText(
  124. // '搜索',
  125. // fontColor: MyColors.color_666666,
  126. // fontSize: 14.sp,
  127. // ),
  128. // ),
  129. // ));
  130. // } else if (!isActionEmpty) {
  131. // list.addAll(widget.actions);
  132. // }
  133. return list;
  134. }
  135. @override
  136. Widget build(BuildContext context) {
  137. return Container(
  138. margin: const EdgeInsetsDirectional.only(end: 10),
  139. height: widget.height,
  140. decoration: BoxDecoration(
  141. borderRadius: BorderRadius.circular(widget.borderRadius ?? 0),
  142. border: Border.all(width: 0.5, color: DarkThemeUtil.multiColors(Colors.black, darkColor: Colors.white)!),
  143. ),
  144. child: Row(
  145. crossAxisAlignment: CrossAxisAlignment.center,
  146. children: [
  147. //间距
  148. SizedBox(width: 10),
  149. //Search Icon
  150. MyAssetImage(
  151. Assets.baseLibBlackBack,
  152. width: 16,
  153. height: 16,
  154. color: DarkThemeUtil.multiColors(null, darkColor: Colors.white),
  155. ).onTap(() {
  156. String? searchStr = _controller?.text;
  157. if (widget.onSearch != null) {
  158. widget.onSearch!(searchStr!);
  159. }
  160. }),
  161. //间距
  162. SizedBox(width: 8),
  163. //输入框
  164. Expanded(
  165. // 权重
  166. child: IgnoreKeyboardDismiss(
  167. child: TextField(
  168. cursorColor: ColorConstants.appBlue,
  169. autofocus: widget.autoFocus ?? false,
  170. // 是否自动获取焦点
  171. focusNode: _focusNode,
  172. // 焦点控制
  173. controller: _controller,
  174. // 与输入框交互控制器
  175. //装饰
  176. decoration: InputDecoration(
  177. isDense: true,
  178. //清除垂直方向的填充
  179. isCollapsed: true,
  180. //让文字垂直居中
  181. border: InputBorder.none,
  182. hintText: widget.hintText ?? '搜索'.tr,
  183. hintStyle: const TextStyle(
  184. fontSize: 15,
  185. color: const Color(0xff777777),
  186. fontWeight: FontWeight.w500,
  187. ),
  188. ),
  189. style: TextStyle(
  190. fontSize: 15,
  191. color: DarkThemeUtil.multiColors(Colors.black, darkColor: Colors.white),
  192. fontWeight: FontWeight.w500,
  193. ),
  194. // 键盘动作右下角图标
  195. textInputAction: TextInputAction.search,
  196. textAlignVertical: TextAlignVertical.center,
  197. onTap: widget.onTap,
  198. // 输入框内容改变回调
  199. onChanged: widget.onChanged,
  200. onSubmitted: widget.onSearch, //输入框完成触发
  201. ),
  202. ),
  203. ),
  204. _suffix(),
  205. ],
  206. ),
  207. );
  208. }
  209. @override
  210. void dispose() {
  211. _controller?.dispose();
  212. _focusNode?.dispose();
  213. super.dispose();
  214. }
  215. }