基础组件库
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

search_tab_widget.dart 7.5 KiB

před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
před 4 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import 'dart:convert';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:cached_network_image/cached_network_image.dart';
  5. import 'package:tab_indicator_styler/tab_indicator_styler.dart';
  6. import 'package:zhiying_base_widget/pages/search_page/item/search_item_page.dart';
  7. import 'package:zhiying_base_widget/pages/search_page/notifier/search_tag_notifier.dart';
  8. import 'package:zhiying_base_widget/pages/search_result_page/search_result_page.dart';
  9. import 'package:zhiying_base_widget/pages/search_think_page/bloc/search_think_bloc.dart';
  10. import 'package:zhiying_base_widget/pages/search_think_page/model/search_think_model.dart';
  11. import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart';
  12. import 'package:zhiying_base_widget/widgets/search/input/model/search_tab_bar_event.dart';
  13. import 'package:zhiying_base_widget/widgets/search/tabbar/search_tab_sk.dart';
  14. import 'package:zhiying_base_widget/widgets/search/widget/my_tab.dart';
  15. import 'package:flutter_bloc/flutter_bloc.dart';
  16. import 'package:zhiying_comm/zhiying_comm.dart';
  17. import 'package:provider/provider.dart';
  18. import 'model/search_tab_model.dart';
  19. class SearchTabWidget extends StatefulWidget {
  20. final Map<String, dynamic> data;
  21. SearchTabModel model;
  22. SearchTabWidget(this.data, {Key key}) : super(key: key) {
  23. try {
  24. model = SearchTabModel.fromJson(jsonDecode(data['data']));
  25. } catch (e) {
  26. Logger.error(e.toString());
  27. }
  28. }
  29. @override
  30. _SearchTabWidgetState createState() => _SearchTabWidgetState();
  31. }
  32. class _SearchTabWidgetState extends State<SearchTabWidget> {
  33. TabController _tabController;
  34. String _type = GlobalConfig.PROVIDER_TB;
  35. /// 联想列表的item点击事件
  36. _onThinkItemClick(SearchThinkModel model) {
  37. model.type = _type;
  38. RouterUtil.hideKeyboard(context);
  39. Provider.of<SearchTagNotifier>(context, listen: false).addTag(model?.keywords);
  40. BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkShowBaseViewEvent());
  41. Navigator.push(
  42. context, CupertinoPageRoute(builder: (_) => SearchResultPage(model.toJson()..['tag'] = 'search_page')));
  43. }
  44. @override
  45. void initState() {
  46. _tabController = TabController(length: widget?.model?.search_icon_list?.length ?? 0, vsync: ScrollableState())
  47. ..addListener(() {
  48. // String type = '';
  49. // try{
  50. // type = widget.model.search_icon_list[_tabController.index].type;
  51. // }catch(_){}
  52. // if(!EmptyUtil.isEmpty(type)) {
  53. // BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkChangeTypeEvent(type));
  54. // }
  55. if (!_tabController.indexIsChanging) {
  56. Logger.log('_tabController.indexIsChanging = ${_tabController?.index}');
  57. try {
  58. _type = widget.model.search_icon_list[_tabController.index].type;
  59. Provider.of<SearchTagNotifier>(context, listen: false).setType(_type);
  60. EventUtil.instance.fire(SearchTabBarEvent(_type));
  61. } catch (e, s) {
  62. Logger.error(e, s);
  63. }
  64. }
  65. });
  66. for (int i = 0; i < widget?.model?.search_icon_list?.length ?? 0; i++) {
  67. if (Provider.of<SearchTagNotifier>(context, listen: false).getType() == widget?.model?.search_icon_list[i].type) {
  68. _tabController.animateTo(i);
  69. }
  70. }
  71. WidgetsBinding.instance.addPostFrameCallback((_) => setTabSelect());
  72. super.initState();
  73. }
  74. setTabSelect() {
  75. for (int i = 0; i < widget.model.search_icon_list.length; i++) {
  76. print("tab选择的类型" + widget.model.search_icon_list[i].type);
  77. }
  78. // setState(() {
  79. // _tabController.animateTo(2);
  80. // });
  81. }
  82. @override
  83. void dispose() {
  84. _tabController?.dispose();
  85. super.dispose();
  86. }
  87. @override
  88. Widget build(BuildContext context) {
  89. return _getMainWidget(widget?.model);
  90. }
  91. /// 获取主视图
  92. Widget _getMainWidget(SearchTabModel model) {
  93. return Visibility(
  94. replacement: SearchTabSkeleton(),
  95. visible: !EmptyUtil.isEmpty(model),
  96. child: _getTabar(model),
  97. );
  98. }
  99. /// 获取TabBar
  100. Widget _getTabar(SearchTabModel model) {
  101. return Container(
  102. margin: const EdgeInsets.only(/*left: 12.5, right: 12.5,*/ top: 20),
  103. child: Column(
  104. children: <Widget>[
  105. TabBar(
  106. controller: _tabController,
  107. isScrollable: true,
  108. labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
  109. unselectedLabelColor: HexColor.fromHex(model?.nameColor ?? '#999999'),
  110. labelColor: HexColor.fromHex(model?.nameSelectColor ?? '#FF4242'),
  111. // indicatorSize: TabBarIndicatorSize.label,
  112. indicator: MaterialIndicator(
  113. height: 2.5,
  114. topLeftRadius: 8,
  115. topRightRadius: 8,
  116. bottomLeftRadius: 8,
  117. bottomRightRadius: 8,
  118. color: HexColor.fromHex(model?.lineSelectColor ?? '#FF4242'),
  119. horizontalPadding: 25,
  120. ),
  121. tabs: model.search_icon_list.map((item) {
  122. return MyTab(
  123. icon: CachedNetworkImage(
  124. imageUrl: item?.with_icon_color ?? '',
  125. width: 14,
  126. ),
  127. text: item.name,
  128. );
  129. }).toList(),
  130. ),
  131. Expanded(
  132. child: _getItemWidget(model),
  133. ),
  134. ],
  135. ),
  136. );
  137. }
  138. /// 根据输入框,是否显示联想列表还是其它
  139. Widget _getItemWidget(SearchTabModel model) {
  140. return Stack(
  141. children: <Widget>[
  142. _getTabBarView(model),
  143. BlocConsumer<SearchThinkBloc, SearchThinkState>(
  144. listener: (context, state) {},
  145. buildWhen: (prev, current) {
  146. if (current is SearchThinkErrorState) {
  147. return false;
  148. }
  149. return true;
  150. },
  151. builder: (context, state) {
  152. // return Visibility(
  153. // replacement: _getTabBarView(model),
  154. //
  155. // child: _getThinkListWidget(),
  156. // );
  157. if (state is SearchThinkLoadedState) {
  158. return _getThinkListWidget(state.model);
  159. }
  160. return Container();
  161. },
  162. ),
  163. ],
  164. );
  165. }
  166. /// tabBarView
  167. Widget _getTabBarView(SearchTabModel model) {
  168. return TabBarView(
  169. controller: _tabController,
  170. children: model.search_icon_list.map((item) {
  171. // TODO 这里需要和后台沟通改成页面的唯一标示
  172. // return PageFactory.create('search_item_page', item.toJson());
  173. return SearchItemPage(item.toJson());
  174. }).toList(),
  175. );
  176. }
  177. /// 联想列表
  178. Widget _getThinkListWidget(List<SearchThinkModel> model) {
  179. return Container(
  180. color: Colors.white,
  181. height: double.infinity,
  182. child: ListView.builder(
  183. itemBuilder: (context, index) {
  184. SearchThinkModel item = model[index];
  185. return GestureDetector(
  186. onTap: () => _onThinkItemClick(item),
  187. child: Container(
  188. decoration:
  189. BoxDecoration(border: Border(bottom: BorderSide(width: 0.5, color: HexColor.fromHex('#EEEEEE')))),
  190. padding: const EdgeInsets.only(top: 13, bottom: 13),
  191. child: Text(
  192. '${item?.keywords}',
  193. style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14),
  194. ),
  195. ),
  196. );
  197. },
  198. itemCount: model?.length ?? 0,
  199. padding: const EdgeInsets.only(left: 12.5, right: 12.5),
  200. shrinkWrap: true,
  201. ),
  202. );
  203. }
  204. }