基础组件库
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.
 
 
 
 
 

254 lines
8.3 KiB

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