基础组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

search_input_widget.dart 8.0 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import 'dart:convert';
  2. import 'dart:ui';
  3. import 'package:flutter/material.dart';
  4. import 'package:zhiying_base_widget/pages/search_page/notifier/search_tag_notifier.dart';
  5. import 'package:zhiying_base_widget/pages/search_result_page/search_result_page.dart';
  6. import 'package:zhiying_base_widget/pages/search_think_page/bloc/search_think_bloc.dart';
  7. import 'package:zhiying_base_widget/pages/search_think_page/search_think_page.dart';
  8. import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart';
  9. import 'package:zhiying_base_widget/widgets/search/input/model/search_input_model.dart';
  10. import 'package:zhiying_base_widget/widgets/search/input/search_input_sk.dart';
  11. import 'package:zhiying_comm/zhiying_comm.dart';
  12. import 'package:provider/provider.dart';
  13. import 'package:cached_network_image/cached_network_image.dart';
  14. import 'package:flutter_bloc/flutter_bloc.dart';
  15. import 'package:fluttertoast/fluttertoast.dart';
  16. ///
  17. /// 搜索页的搜索框
  18. ///
  19. class SearchInputWidget extends StatefulWidget {
  20. final Map<String, dynamic> data;
  21. SearchInputModel model;
  22. SearchInputWidget(this.data, {Key key}) : super(key: key) {
  23. try {
  24. model = SearchInputModel.fromJson(jsonDecode(data['data']));
  25. } catch (e) {
  26. Logger.error(e);
  27. }
  28. }
  29. @override
  30. _SearchInputWidgetState createState() => _SearchInputWidgetState();
  31. }
  32. class _SearchInputWidgetState extends State<SearchInputWidget> {
  33. /// 点击搜索按钮
  34. void _onSearchButtomClick() async {
  35. String content = _editingController?.text?.toString()?.trim() ?? '';
  36. /// TODO 保存历史标签
  37. if (!EmptyUtil.isEmpty(content)) {
  38. await Provider.of<SearchTagNotifier>(context, listen: false).addTag(content);
  39. Navigator.push(context, MaterialPageRoute(builder: (_) => SearchResultPage({'keywords': content})));
  40. }else{
  41. Fluttertoast.showToast(msg: '输入内容不能为空!');
  42. }
  43. }
  44. /// 【弃用】打开搜索联想页面
  45. void _openSearchThinkPage(){
  46. Navigator.push(context, MaterialPageRoute(
  47. builder: (_)=> SearchThinkPage({})
  48. ));
  49. }
  50. /// 搜索框值改变
  51. void _searchInputChange(String text){
  52. if(!EmptyUtil.isEmpty(text)){
  53. // 进行网络更新
  54. print('输入框的内容是 $text');
  55. BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkKeyWrodsChangeEvent(text));
  56. }else{
  57. /// 输入框为空的时候,隐藏联想视图,显示原本的视图
  58. BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkShowBaseViewEvent());
  59. }
  60. }
  61. FocusNode _focusNode;
  62. TextEditingController _editingController;
  63. @override
  64. void didChangeDependencies() {
  65. super.didChangeDependencies();
  66. }
  67. @override
  68. void initState() {
  69. _focusNode = FocusNode();
  70. _editingController = TextEditingController();
  71. super.initState();
  72. }
  73. @override
  74. void dispose() {
  75. _focusNode?.unfocus();
  76. _focusNode?.dispose();
  77. _editingController?.dispose();
  78. super.dispose();
  79. }
  80. @override
  81. Widget build(BuildContext context) {
  82. return Visibility(
  83. visible: !EmptyUtil.isEmpty(widget?.model),
  84. replacement: SearchInputSkeleton(),
  85. child: _getMainWidget(widget?.model),
  86. );
  87. }
  88. /// 获取主视图
  89. Widget _getMainWidget(SearchInputModel model) {
  90. return Container(
  91. color: Colors.white,
  92. width: double.infinity,
  93. margin: EdgeInsets.only(top: MediaQueryData.fromWindow(window).padding.top + 7.5, left: 12.5, right: 12.5),
  94. child: Row(
  95. children: <Widget>[
  96. /// 返回键
  97. _getReturnWidget(),
  98. const SizedBox(width: 8.5),
  99. /// 输入框
  100. Expanded(
  101. child: Container(
  102. width: double.infinity,
  103. height: 32,
  104. // margin: const EdgeInsets.only(
  105. // left: 12.5,
  106. // right: 12.5,
  107. // ),
  108. decoration: BoxDecoration(
  109. borderRadius: BorderRadius.circular(25),
  110. color: HexColor.fromHex('#F9F9F9'),
  111. ),
  112. child: Row(
  113. children: <Widget>[
  114. /// 搜索icon
  115. _getSearchIconWidget(model),
  116. const SizedBox(width: 7.5),
  117. /// 搜索输入框
  118. Expanded(child: _getSearchInputWidget(model)),
  119. /// 搜索按钮
  120. _getSearchButtomWidget(model),
  121. ],
  122. ),
  123. ),
  124. ),
  125. ],
  126. ),
  127. );
  128. }
  129. /// 返回键
  130. Widget _getReturnWidget(){
  131. return GestureDetector(
  132. onTap: ()=> Navigator.maybePop(context),
  133. child: Container(
  134. child: Icon(
  135. Icons.arrow_back_ios,
  136. size: 22,
  137. color: HexColor.fromHex('#333333'),
  138. ),
  139. // onPressed: () => Navigator.maybePop(context),
  140. ),
  141. );
  142. }
  143. /// 搜索icon
  144. Widget _getSearchIconWidget(SearchInputModel model) {
  145. return Container(
  146. height: double.infinity,
  147. width: 20,
  148. margin: const EdgeInsets.only(left: 12.5),
  149. padding: const EdgeInsets.symmetric(vertical: 6),
  150. child: CachedNetworkImage(
  151. imageUrl: model?.search_icon ?? '',
  152. ),
  153. );
  154. }
  155. /// 搜索输入框
  156. Widget _getSearchInputWidget(SearchInputModel model) {
  157. return Container(
  158. height: double.infinity,
  159. alignment: Alignment.centerLeft,
  160. decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: HexColor.fromHex('#F9F9F9')),
  161. // padding: const EdgeInsets.symmetric(vertical: 6),
  162. child: TextField(
  163. showCursor: true,
  164. // readOnly: true,
  165. // onTap: ()=> _openSearchThinkPage(),
  166. onChanged: (val)=> _searchInputChange(val),
  167. cursorWidth: 1,
  168. onSubmitted: (text) => _onSearchButtomClick(),
  169. controller: _editingController,
  170. focusNode: _focusNode,
  171. cursorColor: Colors.transparent,
  172. style: TextStyle(fontSize: 14, color: HexColor.fromHex('#333333')),
  173. decoration: InputDecoration(
  174. filled: false,
  175. // focusColor: Colors.transparent,
  176. // fillColor: Colors.transparent,
  177. border: InputBorder.none,
  178. focusedBorder: InputBorder.none,
  179. focusedErrorBorder: InputBorder.none,
  180. errorBorder: InputBorder.none,
  181. disabledBorder: InputBorder.none,
  182. enabledBorder: InputBorder.none,
  183. hintText: model?.search_inpu_hint_text ?? '搜索更多优惠商品',
  184. hintStyle: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 14),
  185. ),
  186. ),
  187. );
  188. }
  189. /// 搜索按钮
  190. Widget _getSearchButtomWidget(SearchInputModel model) {
  191. return GestureDetector(
  192. behavior: HitTestBehavior.opaque,
  193. onTap: () => _onSearchButtomClick(),
  194. child: Container(
  195. padding: const EdgeInsets.symmetric(horizontal: 17.5, vertical: 6),
  196. decoration: BoxDecoration(
  197. gradient: LinearGradient(
  198. colors: [HexColor.fromHex(model?.search_button_color ?? '#FD5E5E'), HexColor.fromHex(model?.search_button_t ?? '#FF0100')],
  199. begin: Alignment.centerLeft,
  200. end: Alignment.centerRight),
  201. borderRadius: BorderRadius.circular(30),
  202. ),
  203. child: Text(
  204. model?.search_button ?? '搜索',
  205. style: TextStyle(color: HexColor.fromHex('#FFFFFF'), fontSize: 14),
  206. ),
  207. ),
  208. );
  209. }
  210. /// 【弃用】搜索按钮
  211. // Widget _getSearchButtomWidget() {
  212. // return Material(
  213. // child: Container(
  214. // decoration: BoxDecoration(
  215. // borderRadius: BorderRadius.only(topRight: Radius.circular(25), bottomRight: Radius.circular(25))
  216. // ),
  217. // height: double.infinity,
  218. // width: 63,
  219. // child: RaisedButton(
  220. // padding: const EdgeInsets.only(bottom: 6, top: 6, left: 17.5, right: 17.5),
  221. // shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 25)),
  222. // child: Text('搜索', style: TextStyle( fontSize: 14, color: HexColor.fromHex('#FFFFFF')),),
  223. // onPressed: ()=> _onSearchButtomClick(),
  224. // color: HexColor.fromHex('#FF0100'),
  225. // ),
  226. // ),
  227. // );
  228. // }
  229. }