search_app_bar.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.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.value,
  13. this.autoFocus = false,
  14. this.focusNode,
  15. this.controller,
  16. this.actions = const [],
  17. this.hintText,
  18. this.onTap,
  19. this.searchBarHeight = 35,
  20. this.searchBarBorderRadius = 17.25,
  21. this.searchBarBgColor,
  22. this.textHintColor,
  23. this.searchBarBorder,
  24. this.margin,
  25. this.textColor = Colors.white,
  26. this.onChanged,
  27. this.onSearch,
  28. }) : super(key: key);
  29. final bool? autoFocus;
  30. final FocusNode? focusNode;
  31. final TextEditingController? controller;
  32. // 搜索框右侧组件
  33. final List<Widget> actions;
  34. // 输入框提示文字
  35. final String? hintText;
  36. // 输入框点击回调
  37. final VoidCallback? onTap;
  38. double searchBarHeight;
  39. double searchBarBorderRadius;
  40. EdgeInsetsGeometry? margin;
  41. Color? searchBarBgColor;
  42. Color? textHintColor;
  43. Color textColor;
  44. BoxBorder? searchBarBorder;
  45. String? value;
  46. // 输入框内容改变
  47. final ValueChanged<String>? onChanged;
  48. // 点击键盘搜索
  49. final ValueChanged<String>? onSearch;
  50. @override
  51. _SearchAppBarState createState() => _SearchAppBarState();
  52. }
  53. class _SearchAppBarState extends State<SearchAppBar> {
  54. TextEditingController? _controller;
  55. FocusNode? _focusNode;
  56. bool get isFocus => _focusNode?.hasFocus ?? false; //是否获取焦点
  57. bool get isTextEmpty => _controller?.text.isEmpty ?? false; //输入框是否为空
  58. bool get isActionEmpty => widget.actions.isEmpty; // 右边布局是否为空
  59. bool isShowCancel = false;
  60. @override
  61. void initState() {
  62. _controller = widget.controller ?? TextEditingController();
  63. _focusNode = widget.focusNode ?? FocusNode();
  64. //赋值要显示的文本
  65. if (widget.value != null) _controller?.text = widget.value ?? "";
  66. super.initState();
  67. }
  68. // 更新输入框的文本内容
  69. void updateValue(String newValue) {
  70. setState(() {
  71. _controller?.text = newValue;
  72. });
  73. }
  74. //失去焦点和隐藏软键盘
  75. void _unFocus() {
  76. setState(() {
  77. _focusNode?.unfocus();
  78. });
  79. }
  80. @override
  81. void didUpdateWidget(covariant SearchAppBar oldWidget) {
  82. super.didUpdateWidget(oldWidget);
  83. if (widget.value != oldWidget.value) {
  84. _controller?.text = widget.value ?? "";
  85. }
  86. }
  87. @override
  88. Widget build(BuildContext context) {
  89. return Container(
  90. height: widget.searchBarHeight,
  91. padding: const EdgeInsets.only(left: 15, right: 11),
  92. margin: widget.margin ?? const EdgeInsets.only(right: 15),
  93. decoration: BoxDecoration(
  94. color: widget.searchBarBgColor ?? Color(0xFF4DCFF6).withOpacity(0.2), // 设置// 背景颜色和不透明度
  95. borderRadius: BorderRadius.circular(widget.searchBarBorderRadius), // 设置圆角
  96. border: widget.searchBarBorder,
  97. ),
  98. child: Row(
  99. mainAxisSize: MainAxisSize.max,
  100. crossAxisAlignment: CrossAxisAlignment.center,
  101. children: [
  102. //输入框
  103. IgnoreKeyboardDismiss(
  104. child: TextField(
  105. cursorColor: widget.textColor,
  106. cursorWidth: 1.5,
  107. autofocus: false,
  108. maxLines: 1,
  109. minLines: 1,
  110. // 是否自动获取焦点
  111. focusNode: _focusNode,
  112. // 焦点控制
  113. controller: _controller,
  114. // 与输入框交互控制器
  115. //装饰
  116. decoration: InputDecoration(
  117. isDense: true,
  118. //清除垂直方向的填充
  119. isCollapsed: true,
  120. //让文字垂直居中
  121. border: InputBorder.none,
  122. hintText: widget.hintText,
  123. hintStyle: TextStyle(
  124. color: widget.textHintColor ?? Color(0xFFAECAE5),
  125. fontSize: 15.0,
  126. fontWeight: FontWeight.w400,
  127. ),
  128. ),
  129. style: TextStyle(
  130. color: widget.textColor,
  131. fontSize: 15.0,
  132. fontWeight: FontWeight.w400,
  133. ),
  134. // 键盘动作右下角图标
  135. textInputAction: TextInputAction.search,
  136. textAlignVertical: TextAlignVertical.center,
  137. onSubmitted: (value) {
  138. widget.onSearch?.call(value);
  139. _unFocus();
  140. },
  141. //输入框完成触发
  142. onChanged: (value) {
  143. widget.value = value;
  144. widget.onChanged?.call(value);
  145. },
  146. ),
  147. ).expanded(),
  148. //搜索图标
  149. const MyAssetImage(Assets.baseLibSearchIcon, width: 15, height: 15).marginOnly(left: 10).onTap(() {
  150. widget.onSearch?.call(_controller?.text ?? "");
  151. _unFocus();
  152. }),
  153. ],
  154. ),
  155. );
  156. }
  157. @override
  158. void dispose() {
  159. _controller?.dispose();
  160. _focusNode?.dispose();
  161. super.dispose();
  162. }
  163. }